Oracle PL/SQL:使用绑定变量进行查询
能否请您帮助理解,是否有可能使这项工作使用绑定变量 第1步: =>例如,d_sql_查询可以类似于'CD_UNBIL.trans_dt>=TO_DATE('20200702 12:11:03','YYYYMMDD HH24:MI:SS'),或者d_sql_查询可以有更大的条件 稍后,我们将此d_sql_查询添加到更大的查询中,如下所示:- 第2步 正如您所看到的,d_sql_查询是附加的,因此整个查询如下所示Oracle PL/SQL:使用绑定变量进行查询,oracle,plsql,oracle11g,Oracle,Plsql,Oracle11g,能否请您帮助理解,是否有可能使这项工作使用绑定变量 第1步: =>例如,d_sql_查询可以类似于'CD_UNBIL.trans_dt>=TO_DATE('20200702 12:11:03','YYYYMMDD HH24:MI:SS'),或者d_sql_查询可以有更大的条件 稍后,我们将此d_sql_查询添加到更大的查询中,如下所示:- 第2步 正如您所看到的,d_sql_查询是附加的,因此整个查询如下所示 ... AND RPU_WORK.tracking_id = :tracking_id
...
AND RPU_WORK.tracking_id = :tracking_id AND RPU_WORK.tracking_id_serv = :tracking_id_serv AND '|| NVL(CD_UNBIL.trans_dt >= TO_DATE('20200702 12:11:03', 'YYYYMMDD HH24:MI:SS'), ' 1=1 ');
我希望这样做(使用下面的绑定变量)
一旦我有了上面的查询,我就可以使用“executeimmediateusing”。您能这样构造查询的结尾吗
...
AND RPU_WORK.tracking_id = :tracking_id
AND RPU_WORK.tracking_id_serv = :tracking_id_serv
AND case when :b1 is not null
then
case when CD_UNBIL.trans_dt >= TO_DATE(:b1, 'YYYYMMDD HH24:MI:SS')
then 1
else 0
end
else 1
end = 1
您可以使用我的开源程序动态查找文本,并使用绑定变量替换文本 例如:
--Convert literals to bind variables.
declare
v_sql_expression clob := q'[CD_UNBIL.trans_dt >= TO_DATE('20200702 12:11:03', 'YYYYMMDD HH24:MI:SS')]';
v_new_sql_expression clob;
v_tokens token_table := token_table();
v_bind_number number := 0;
begin
v_tokens := plsql_lexer.lex(v_sql_expression);
for i in 1 .. v_tokens.count loop
if v_tokens(i).type in ('text', 'numeric') then
v_new_sql_expression := v_new_sql_expression || ':b'||v_bind_number;
v_bind_number := v_bind_number + 1;
else
v_new_sql_expression := v_new_sql_expression || v_tokens(i).value;
end if;
end loop;
dbms_output.put_line('New expression: '||v_new_sql_expression);
end;
/
输出:
New expression: CD_UNBIL.trans_dt >= TO_DATE(:b0, :b1)
这段代码会有一些问题,TO_DATE
有两个变量,而不是一个,日期文本,如日期'2000-01-01'需要特殊处理,因为它实际上是三个令牌而不是一个,这不会阻止SQL注入(正如pmdba指出的),您需要调整上述代码,以便从正确的表中读取,然后存储并应用文本,等等
这可能有助于全面解释您试图解决的问题-为什么不简单地将动态表达式作为文本应用,而不是尝试使用绑定变量?这里的问题是d_sql_查询可以具有任何运算符的任何条件,不仅仅是如上所示的日期,您将无法以这种方式完全转换为绑定变量。只要“where”子句可以包含用户输入,您就必须连接文本,并且会有潜在的SQL注入问题。我们的DBA建议使用具有不同值的绑定变量进行d_sql_查询,最终查询每次都会更改为新的sql_id,DBA无法对其进行优化。
...
AND RPU_WORK.tracking_id = :tracking_id
AND RPU_WORK.tracking_id_serv = :tracking_id_serv
AND case when :b1 is not null
then
case when CD_UNBIL.trans_dt >= TO_DATE(:b1, 'YYYYMMDD HH24:MI:SS')
then 1
else 0
end
else 1
end = 1
--Convert literals to bind variables.
declare
v_sql_expression clob := q'[CD_UNBIL.trans_dt >= TO_DATE('20200702 12:11:03', 'YYYYMMDD HH24:MI:SS')]';
v_new_sql_expression clob;
v_tokens token_table := token_table();
v_bind_number number := 0;
begin
v_tokens := plsql_lexer.lex(v_sql_expression);
for i in 1 .. v_tokens.count loop
if v_tokens(i).type in ('text', 'numeric') then
v_new_sql_expression := v_new_sql_expression || ':b'||v_bind_number;
v_bind_number := v_bind_number + 1;
else
v_new_sql_expression := v_new_sql_expression || v_tokens(i).value;
end if;
end loop;
dbms_output.put_line('New expression: '||v_new_sql_expression);
end;
/
New expression: CD_UNBIL.trans_dt >= TO_DATE(:b0, :b1)