在前面几天我们写了SQL优化必备脚本:Oracle获取绑定变量的字面SQL文本,其中有网友反馈在SQL中timestamp列返回空置和有两个date类型的列式,会出现将之间:1识别为绑定变量的方式。

关于timestamp返回空值,这个是由于V$SQL_BIND_CAPTURE的机制导致的,详细信息可以查考Mos:444551.1,关于SQL语句中有:1这种值时,会被识别绑定量来替代,所以此时会返回错误的结果。

现象的模拟

declare
  b1   DATE  := to_date('05/11/2025 15:19:56', 'mm/dd/yyyy hh24:mi:ss');
  b2 timestamp:=to_timestamp('05/11/2025 15:19:56', 'mm/dd/yyyy hh24:mi:ss');
begin
execute immediate q'[select count(*) from t1 where created>:2 and last_ddl_time<:1 ]' using b2,b1;
end;
/

脚本返回的结果如下:

SYS@HTZ@ARM19C> @sql_fulltext_by_sqlid.sql
Enter value for sqlid: 8xsugjwa5k75z
SYS
select count(*) from t1 where created>NULL and last_ddl_time<'05/11/2025 15:19:56'

PL/SQL procedure successfully completed.

修复的思路

timestamp按照Mos的解决方案修复即可。
关于:1这种现象采用的是识别常亮值,也就是不替换''中的任何内容即可,这个时候需要我们自己写一个函数来实现。

修复的效果

修复后的脚本执行结果如下:

SYS@HTZ@ARM19C> @sql_fulltext_by_sqlid.sql
Enter value for sqlid: 8xsugjwa5k75z
SYS
select count(*) from t1 where created>'2025-05-11 15:19:56.000000000' and last_ddl_time<'05/11/2025 15:19:56'

PL/SQL procedure successfully completed.

这个问题就修复到这个,如果大家在执行过程中

------------------作者介绍-----------------------

姓名:黄廷忠

现就职:Oracle中国高级服务团队

曾就职:OceanBase、云和恩墨、东方龙马等