【问题标题】:Adding quotes around a date variable at run time - SQL / PL-SQL在运行时为日期变量添加引号 - SQL / PL-SQL
【发布时间】:2017-04-04 12:10:46
【问题描述】:

我在我的 PL-SQL 过程脚本中使用了这一行:

l_query := REPLACE(l_query,'<REF_D>',  REF_D) 

这会导致:

select sum(rec_count) from mt_table_status where table_id = 8942 and ref_d = 15.06.17

但 SQL 没有执行它,因为 REF_D 不在引号 ('') 中

如何将日期变量括在引号中?

附:我试过 QUOTENAME 但我收到一条错误消息:

必须声明标识符quotename

一如既往..任何帮助都非常感谢..

【问题讨论】:

  • 问题不是很清楚;结果字符串应该是什么?另外,您似乎使用的是动态 SQL,那么为什么不使用绑定变量呢?
  • 为什么使用字符串作为 DATE 值?
  • @Aleksej: 非常感谢.. 不知道绑定变量是什么..:) 但您对动态 sql 的想法有所帮助..

标签: sql oracle plsql oracle-sqldeveloper


【解决方案1】:

如果我理解得很好,您有一些动态 SQL 想要修改以使用变量值作为过滤器。

假设您无法编辑查询,这是一种处理双引号的方法,同时将占位符替换为变量值;例如:

declare
    vSQL    varchar2(100);
    vVar    varchar2(10);
    vNum    number;
begin    
    vSQL := 'select count(*) from dual where ''a'' = <SOME_VAR>';
    vVar := 'a';
    --
    vSQL := replace (vSQL, '<SOME_VAR>', '''' || vVar || '''');
    execute immediate vSQL into vNum;
    dbms_output.put_line('Result: ' || vNum);
end;

如果您可以编辑动态 SQL,更好的方法是在 SQL 部分处理双引号,而不是在变量替换部分处理;例如:

declare
    vSQL    varchar2(100);
    vVar    varchar2(10);
    vNum    number;
begin    
    vSQL := 'select count(*) from dual where ''a'' = ''<SOME_VAR>''';
    vVar := 'a';
    --
    vSQL := replace (vSQL, '<SOME_VAR>', vVar);
    execute immediate vSQL into vNum;
    dbms_output.put_line('Result: ' || vNum);
end;

另一种方法(恕我直言最好的方法)可能是使用绑定变量;例如:

declare
    vSQL    varchar2(100);
    vVar    varchar2(10);
    vNum    number;
begin    
    vSQL := 'select count(*) from dual where ''a'' = :SOME_VAR';
    vVar := 'a';
    --
    execute immediate vSQL into vNum using vVar;
    dbms_output.put_line('Result: ' || vNum);
end;

这假设您的数据类型是字符串,即使您可能需要日期;如果您有日期值,请考虑前两种方法需要与字符串进行转换,而您可以轻松地将绑定变量与日期变量一起使用,而无需强制转换;例如:

declare
    vSQL    varchar2(100);
    vVar    date;
    vNum    number;
begin    
    vSQL := 'select count(*) from dual where trunc(sysdate) = :SOME_VAR';
    vVar := trunc(sysdate);
    --
    execute immediate vSQL into vNum using vVar;
    dbms_output.put_line('Result: ' || vNum);
end;

【讨论】:

    【解决方案2】:

    正确的做法是使用参数。

    但是,如果您想通过替换字符串中的值来执行此操作,请使用单引号定义字符串。在 SQL 中,您可以通过将单引号加倍来做到这一点:

    l_query := 'select sum(rec_count) from mt_table_status where table_id = 8942 and ref_d = ''<REF_D>''';
    

    【讨论】:

      【解决方案3】:

      我会使用 to_date 函数将您的(我认为是字符串)ref_d 参数转换为日期

      declare
      l_query varchar2(1024) := 'select sum(rec_count) from mt_table_status where table_id = 8942 and ref_d = <REF_D>'; 
      ref_d varchar2(100) := '09.12.16';
      begin
       l_query := replace(l_query,'<REF_D>','to_date('''||ref_d||''',''dd.mm.yy'')');
       dbms_output.put_line(l_query);
      end;
      

      输出:

      select sum(rec_count) from mt_table_status where table_id = 8942 and ref_d = to_date('09.12.16','dd.mm.yy')
      

      【讨论】:

      • 我试过这个..它试图用整个 to_date('09.12.16','dd. mm.yy') 作为字符串..
      • 在@Aleksej 回答中使用第三个代码段(带有变量绑定),动态SQL 不适合您的情况,日期变量的每个新值都会导致重新编译SQL,注意编译不是廉价操作,可能,它会比 SQL 执行本身花费更多的时间。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-07
      • 2021-10-19
      • 1970-01-01
      • 2018-09-23
      • 1970-01-01
      • 2017-12-12
      • 1970-01-01
      相关资源
      最近更新 更多