是否可以在 Oracle SQL*plus 脚本中以编程方式构造替换变量的名称?
Posted
技术标签:
【中文标题】是否可以在 Oracle SQL*plus 脚本中以编程方式构造替换变量的名称?【英文标题】:Is it possible to programmatically construct the name of a substitution variable in Oracle SQL*plus scripts? 【发布时间】:2012-07-18 19:46:11 【问题描述】:我正在尝试编写一个运行单个任意过程的 sql*plus 脚本。棘手的部分是我希望能够运行该过程,而不管该过程需要多少参数。
为了找出过程的正确参数数量,我正在执行以下操作:
SELECT COUNT(*) INTO v_in
FROM all_arguments
WHERE LOWER(owner) = LOWER(v_schema)
AND LOWER(package_name) = LOWER(v_package)
AND LOWER(object_name) = LOWER(v_proc)
AND in_out = 'IN';
当需要构建立即执行字符串时,我想使用某种循环来做到这一点。传入的参数都只是编号,从 &1 到 &n。
FOR i IN 1..v_in
LOOP
v_block := v_block || '''' || &i || '''';
IF i != v_in THEN
v_block := v_block || ',';
END IF;
END LOOP;
但这不起作用。它看到 &i 并且当然认为它是一个名为 i 的参数,并且由于调度应用程序(Appworx ... ugh)没有运行定义 i=something,因此失败得很惨。
有没有办法在这方面做间接,这样我就可以迭代,但是对于给定的过程有很多碰巧是正确的?
【问题讨论】:
从 &i 中删除 & ?这只是一个变量,对吧? 是的,但是我需要(在循环中)添加第 4 个参数,然后是第 5 个参数,然后是第 6 个参数,依此类推,直到我获取了该脚本的所有参数文件。我需要扩展为 &4 和 &5 等的东西。 【参考方案1】:您可以使用 new_value 和默认 SQL*Plus 参数来欺骗它。
创建一个这样的脚本,例如 test.sql:
-- hide output
set termout off
-- define parameter variables to be set with new_value
col par1 new_value 1 noprint
col par2 new_value 2 noprint
col par3 new_value 3 noprint
-- initialize parameter variables
select 1 par1, 2 par2, 3 par3 from dual where 1=2;
-- append comma to parameter variables, not needed for first parameter
select nullif(','||'&2',',') par2, nullif(','||'&3',',') par3 from dual;
-- show output
set termout on
-- you actual script starts here
prompt calling procedure my_proc(&1 &2 &3)
-- for next run
undef 1
undef 2
undef 3
现在拨打@test 3 4
输出:
calling procedure my_proc(3 ,4 )
或拨打@test 1 2 3
输出:
calling procedure my_proc(1 ,2 ,3 )
现在您需要将此扩展到您的参数的最大预期数量。
(请注意,您必须先登录才能进行此操作,否则select from dual
将静默失败。)
【讨论】:
【参考方案2】:你想做动态sql,不知道会涉及多少参数。 Asktom has the authoritative answer for this。不要为“新”方法而烦恼。它不适合你,因为你不知道会有多少参数。
基本上,您将通过连接创建动态 sql,但参数将存储在 sys_context
中,以便查询具有绑定。这有助于解决 SQL 注入等问题。
【讨论】:
Tom Kyte 自己提出了一种不同的方法,您始终使用所有绑定变量(链接自上述文章),请参阅asktom.oracle.com/pls/asktom/… 如果你不知道会有多少绑定变量,那就很难做到。 你是对的,当然——我在考虑一个具有固定数量参数的过程,你只想使用非空参数来限制结果集。对不起。以上是关于是否可以在 Oracle SQL*plus 脚本中以编程方式构造替换变量的名称?的主要内容,如果未能解决你的问题,请参考以下文章