Oracle SQL-使用if子句驱动变量

Oracle SQL-使用if子句驱动变量,oracle,plsql,Oracle,Plsql,大家早上好 我编写了以下查询: 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 DateFro

大家早上好

我编写了以下查询:

    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;
理论是,最终用户可以设置变量,查询将基于变量集进行构建,如果他们将其设置为nothing,if语句基本上将该子句从最终查询中排除

如果我提供所有变量并删除If,那么我认为变量没有正确地传递到If中,但我不确定


有没有人实现过这一点,或者知道我为什么不工作?

我会使用绑定变量(
:variable
)而不是替换变量(
&variable

另外,您可以在
where
子句中使用
case
语句,而不是
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
,它不是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'))

不幸的是,您不能为选项变量指定格式,这会很方便。

我不确定您是否理解问题的要点,如果变量为null,则应排除整个子句