Oracle SQL - использование предложений if для управления переменными - PullRequest
0 голосов
/ 25 июня 2018

Доброе утро всем

Я написал следующий запрос:

    define AssetVar = "'BA G-ZBJA'"
define DateFromVar = "'12/08/2016 15:00:00'"

define AssetClause = " where Asset = &AssetVar";
define

BEGIN
  IF DateFromVar = ""
    Then define DateFromClause = ""
    ELSE
    define DateFromClause ="and DATETIME >= TO_DATE(&DateFromVar, 'dd/mm/yyyy hh24:mi:ss')";
  End IF;
End;
define

select * from SCHEDULE &AssetClause &DateFromClause ;

undefine AssetVar DateFromVar AssetClause DateFromClause;

Теория заключается в том, что конечный пользователь может устанавливать переменные, и запрос будет построен на основе установленных переменных, если они устанавливают его в ничто, оператор if в основном исключает это предложение из окончательного запроса.

Если я предоставлю все переменные и удалю IF, все в порядке, я думаю, что переменные не передаются в IFправильно, но я не уверен

Кто-нибудь когда-либо достигал этого или знает, почему я не работаю?

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

define - это клиент команда , она не является частью синтаксиса PL / SQL (или даже SQL).Вы можете ссылаться на переменные замещения в анонимном блоке PL / SQL, но они оцениваются, затем блок компилируется, и вы не можете изменить их значения.

Вы можете переместить всю эту логику в запрос, например:

define AssetVar = "BA G-ZBJA"
define DateFromVar = "12/08/2016 15:00:00"

select * from SCHEDULE
where Asset = '&&AssetVar'
and ('&&DateFromVar' is null or DATETIME >= TO_DATE('&&DateFromVar', 'dd/mm/yyyy hh24:mi:ss'));

С set verify on вы можете увидеть SQL, который у вас получится:

old:select * from SCHEDULE
where Asset = '&&AssetVar'
and ('&&DateFromVar' is null or DATETIME >= TO_DATE('&&DateFromVar', 'dd/mm/yyyy hh24:mi:ss'))
new:select * from SCHEDULE
where Asset = 'BA G-ZBJA'
and ('12/08/2016 15:00:00' is null or DATETIME >= TO_DATE('12/08/2016 15:00:00', 'dd/mm/yyyy hh24:mi:ss'))

Если вы определяете значения, тогда логика немного бессмысленна;скорее всего, вы подсказываете:

accept AssetVar
accept DateFromVar

with schedule(asset, datetime) as (select 'test', sysdate from dual)
select * from SCHEDULE
where Asset = '&&AssetVar'
and ('&&DateFromVar' is null or DATETIME >= TO_DATE('&&DateFromVar', 'dd/mm/yyyy hh24:mi:ss'));

, поэтому, если вы не введете значение даты, сравнение закончится следующим образом:

...
and ('' is null or DATETIME >= TO_DATE('', 'dd/mm/yyyy hh24:mi:ss'))

К сожалению, вы не можете указать форматдля переменной option, которая была бы удобна.

0 голосов
/ 25 июня 2018

Я бы использовал переменные связывания (:variable) вместо переменных замещения (&variable).

Кроме того, вы можете использовать оператор case в предложении where вместо if.

Таким образом, решение будет выглядеть примерно так:

select * from SCHEDULE
where 
Asset = :AssetVar and 
case when DateFromClause = ''  
         then 1
else 
          case when DATETIME >= TO_DATE(:DateFromVar, 'dd/mm/yyyy hh24:mi:ss')
               then 1
          else 
                    0
          end
end   
     = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...