在动态sql中使用集合

时间:2017-02-08 08:13:19

标签: oracle plsql numbers dynamic-sql

我试图将dbms_sql.number_table从一个过程传递到另一个过程,然后在动态plsql块中使用它。但是下面的代码会抛出错误:

  

错误(6,17):PLS-00306:调用'||'时参数的数量或类型错误

create or replace
procedure proc1( v_in_table_name varchar2,
                 v_in_column_name varchar2,
                 v_in dbms_sql.number_table)
as
plsql_block varchar2(4000);
begin
   plsql_block:='declare

                 begin
                      FORALL INDX IN 1 ..'||v_in.count||'  SAVE EXCEPTIONS 
                       UPDATE '||v_in_table_name||'
                         Set '||v_in_column_name||'=123 WHERE col2='||v_in||'(INDX)||;
                 end';
    execute immediate plsql_block;
end proc1;

2 个答案:

答案 0 :(得分:0)

您应该进行两项更改: 第一个(和它的错误情况)当你用字符串连接时。 如果你想将集合发送到pl / sql块,你应该使用param。 第二,你应该在动态pl \ sql:

的末尾添加create or replace procedure proc1(v_in dbms_sql.number_table) as plsql_block varchar2(4000); begin plsql_block:='declare l_collect dbms_sql.number_table := :number_table ; begin FORALL INDX IN 1 ..'||v_in.count||' SAVE EXCEPTIONS UPDATE table_name Set col1=123 WHERE col2=l_collect(INDX); end;'; execute immediate plsql_block using v_in; end proc1;
<li class="item item-toggle">
     Following
     <label class="toggle toggle-balanced">
       <input type="checkbox" ng-model="set_following" ng-checked="following == 'yes'" ng-change="following()">
       <div class="track">
         <div class="handle"></div>
       </div>
     </label>
  </li>

但是经过所有更改之后我想问一下:你真的需要使用动态pl \ sql吗?

答案 1 :(得分:0)

无需使用动态块。另外我不认为它可以工作。你可以用这种方式;

create or replace
procedure proc1(v_in dbms_sql.number_table)
as
plsql_block varchar2(4000);

l_collect dbms_sql.number_table;

begin

l_collect := v_in;

 FORALL INDX IN 1 ..l_collect.count  SAVE EXCEPTIONS 
      UPDATE table_name
    Set col1=123 
    WHERE col2=l_collect(INDX);

 commit; 
end proc1;

执行:

 SQL> DECLARE
       var   DBMS_SQL.number_table;
       BEGIN
         var (1) := 1;
         var (2) := 2;
         var (3) := 3;
        proc1 (var);
       END;    
     /

PL/SQL procedure successfully completed.

编辑:根据您的编辑,代码变为:

 create or replace procedure proc1 (v_in_table_name     varchar2,
                                   v_in_column_name    varchar2,
                                   v_in                dbms_sql.number_table)
as
   plsql_block   varchar2 (4000);
begin
   plsql_block := q'[ FORALL INDX IN 1 ..v_in.count  SAVE EXCEPTIONS 
                          UPDATE :table_name
                          Set :col1=123 
                          WHERE col2=v_in(INDX)]';

   execute immediate plsql_block using v_in_table_name, v_in_column_name;

   commit;
end proc1;