如何通过使用代码更改变量名来动态使用变量

想要一种通过在plsql块中动态更改其名称来引用不同变量的方法。

尝试了简单的循环,该循环将更改变量的有效名称。 使用语句编写一个级联的plsql块,但是由于现有代码的大小,没有用。

set serveroutput on;
declare
foo1 number:=111;
foo2 number:=222;
begin
execute immediate 'dbms_output.put_line(foo'||'1)';
for i in 0..2
loop
dbms_output.put_line(foo||i);
end loop;
end;
/

预期输出为111 输出错误如下 错误报告 - ORA-00900:无效的SQL语句 ORA-06512:在第5行 00900. 00000-“无效的SQL语句”

SJ1988GG 回答:如何通过使用代码更改变量名来动态使用变量

您的变量是局部的。 DBMS_OUTPUT软件包不知道它们。因此结果字符串dbms_output.put_line(foo1)不能用execute immediate执行。

解决此问题的典型方法是使用值数组而不是单独的变量

declare
  type t_array is varray(2) of integer;
  v_array t_array := t_array(111,222);
begin
  for i in 1..2 loop
    dbms_output.put_line(v_array(i));
  end loop;
end;

与动态数组相同:

declare
  type t_array is table of integer;
  v_array t_array := t_array();
begin
  v_array.extend(1);
  v_array(1) := 111;
  v_array.extend(1);
  v_array(2) := 222;
  for i in 1 .. v_array.count loop
    dbms_output.put_line(v_array(i));
  end loop;
end;
,

让我们一次迈出一步。首先,可以使用的静态代码:

SQL> declare
  2  foo1 number:=111;
  3  foo2 number:=222;
  4  begin
  5  dbms_output.put_line(foo1);
  6  end;
  7  /

111

现在,如果要立即执行某些文本,则必须在文本中输入所有代码

SQL> declare
  2    l_code_block varchar2(4000) := '
  3  declare
  4  foo1 number:=111;
  5  foo2 number:=222;
  6  begin
  7  dbms_output.put_line(foo2);
  8  end;
  9  ';
 10  begin
 11  execute immediate l_code_block;
 12  end;
 13  /

222

下一步:如果我们要动态更改,我们可以并且应该使用“绑定变量”。

SQL> declare
  2    l_code_block varchar2(4000) := '
  3  declare
  4  foo1 number:=111;
  5  foo2 number:=222;
  6  begin
  7  dbms_output.put_line(:n);
  8  end;
  9  ';
 10  begin
 11  execute immediate l_code_block using 1;
 12  end;
 13  /

1

但是,如果我们尝试使用绑定变量来更改代码,那么它将无法正常工作。

SQL> declare
  2    l_code_block varchar2(4000) := '
  3  declare
  4  foo1 number:=111;
  5  foo2 number:=222;
  6  begin
  7  dbms_output.put_line(foo:n);
  8  end;
  9  ';
 10  begin
 11  execute immediate l_code_block using 1;
 12  end;
 13  /

...
Error report -
ORA-06550: line 6,column 25:
PLS-00103: Encountered the symbol "" when expecting one of the following
...

因此,如果要动态更改代码,则必须对文本进行替换。

SQL> declare
  2    l_code_block varchar2(4000) := '
  3  declare
  4  foo1 number:=111;
  5  foo2 number:=222;
  6  begin
  7  dbms_output.put_line(foo#N#);
  8  end;
  9  ';
 10  begin
 11  execute immediate replace(l_code_block,'#N#',1);
 12  end;
 13  /

111

最后,这是您的循环:

SQL> declare
  2    l_code_block varchar2(4000) := '
  3  declare
  4  foo1 number:=111;
  5  foo2 number:=222;
  6  begin
  7  dbms_output.put_line(foo#N#);
  8  end;
  9  ';
 10  begin
 11    for i in 1..2 loop
 12      execute immediate replace(l_code_block,i);
 13    end loop;
 14  end;
 15  /

111
222

请理解,我正在尝试回答您的问题。应尽可能避免这种“动态”方法,并且几乎总是可能的。为了推荐最合适的技术,我们必须备份业务需求。

最好的问候, 炖阿什顿

本文链接:https://www.f2er.com/3161111.html

大家都在问