1

我正在尝试编写一个运行单个任意过程的 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,因此失败得很惨。

有没有办法在这方面做间接,这样我就可以迭代,但是对于给定的过程有很多碰巧是正确的?

4

2 回答 2

1

你想做动态sql,不知道会涉及多少参数。Asktom 对此有权威的回答。不要为“新”方法而烦恼。它对你不起作用,因为你不知道会有多少参数。

基本上,您将通过连接创建动态 sql,但参数将存储在 a 中sys_context,以便查询具有绑定。这有助于将 SQL 注入之类的事情作为奖励。

于 2012-07-18T20:52:12.583 回答
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会静默失败。)

于 2012-07-19T06:20:26.460 回答