【问题标题】:Oracle Stored Procedure varray beyond countOracle 存储过程 varray 数不胜数
【发布时间】:2015-08-13 13:24:29
【问题描述】:

我创建了 3 个存储过程。他们的每个功能是:
1. proc_insertleveluser -> 插入“leveluser”表并返回最后插入的id
2. proc_insertpermissiondtl -> 插入“permission_dtl”表并返回最后插入的id
3. proc_insert_relation_lpd -> 使用过程 1 和 2 提供的数据插入“lvl_permission_dtl”表

proc_insertleveluser

create or replace procedure proc_insertleveluser(level_desc varchar, level_ int, department_id varchar, r_id_level out int)
as
begin
  insert into leveluser (level_desc, level_, department_id) values (level_desc, level_, department_id)
  returning id_level into r_id_level;
  commit;
end;

proc_insertpermissiondtl

create or replace procedure proc_insertpermissiondtl(status_ int, entry_ int, view_ int, modify_ int, delete_ int, approval_ int, r_id_p_dtl out int)
as
begin
  insert into permission_dtl (status_, entry_, view_, modify_, delete_, approval_)
  values(status_, entry_, view_, modify_, delete_, approval_)
  returning id_p_dtl into r_id_p_dtl;
  commit;
end;

proc_insert_relation_lpd

create or replace procedure proc_insert_relation_lpd(lu_level_desc varchar, lu_level_ int, lu_department_id varchar)
as
  r_id_level int;  /* r_ is for return */
  r_id_p_dtl int;  
  type arr_id_p_dtl is varray(13) of int;
  arraynya arr_id_p_dtl := arr_id_p_dtl();
begin
  proc_insertleveluser(lu_level_desc, lu_level_, lu_department_id, r_id_level); 
  for i in 1..arraynya.count loop  
    proc_insertpermissiondtl(0, 0, 0, 0, 0, 0, r_id_p_dtl);
    arraynya(i) := r_id_p_dtl;
  end loop;

  /* more code here to insert to "lvl_permission_dtl" table */

  commit;
end;

当我执行代码时,1 条记录添加到“leveluser”表中,但没有添加到“permission_dtl”表中。似乎 for 循环内的代码没有执行。

这是什么原因造成的? “arraynya”变量是空的,所以 for 循环不会执行吗?还是有其他问题? :)

【问题讨论】:

  • 看着proc_insert_relation_lpd,在arraynya 使用for 语句之前,我看不到任何东西可以放入arraynya。你期待别的吗?也许你打算使用arraynya.limit而不是使用arraynya.count
  • 好吧,在“开始”语句之前,我想从 arr_id_p_dtl 创建一个空的可变数组“arraynya”,这是一个 13 长度的可变数组,然后用返回的值填充“arraynya”中的每个索引for 循环上的 proc_insertpermissiondtl ......这是正确的方法吗?
  • 正如我所说,我认为您想在 while 循环中使用 arraynya.limit 而不是 arraynya.count。祝你好运。
  • 哦,我是多么愚蠢..非常感谢,我现在明白了..我认为“.count”类似于“.length”或类似的东西..:D
  • 有关可用收集方法的文档,请参阅 PL/SQL Reference: Using Collection Methods

标签: oracle stored-procedures plsql varray


【解决方案1】:

您创建了一个空数组,因此当您进入循环时,count 将为 0。正如 Bob Jarvis 指出的那样,如果您想遍历循环 13 次,您需要使用数组的 limit,而不是 count

SQL> ed
Wrote file afiedt.buf

  1  declare
  2    type arr_id_p_dtl is varray(13) of int;
  3    arraynya arr_id_p_dtl := arr_id_p_dtl();
  4  begin
  5    dbms_output.put_line( 'Count is ' || arraynya.count );
  6    dbms_output.put_line( 'Limit is ' || arraynya.limit );
  7    --
  8    -- This doesn't do anything since the count is 0
  9    --
 10    for i in 1..arraynya.count
 11    loop
 12      dbms_output.put_line( 'Count loop i=' || i );
 13    end loop;
 14    --
 15    -- This will iterate 13 times
 16    --
 17    for i in 1..arraynya.limit
 18    loop
 19      dbms_output.put_line( 'Limit loop i=' || i );
 20    end loop;
 21* end;
 22  /
Count is 0
Limit is 13
Limit loop i=1
Limit loop i=2
Limit loop i=3
Limit loop i=4
Limit loop i=5
Limit loop i=6
Limit loop i=7
Limit loop i=8
Limit loop i=9
Limit loop i=10
Limit loop i=11
Limit loop i=12
Limit loop i=13

PL/SQL procedure successfully completed.

【讨论】:

  • 嗨@JustinCave 不幸的是我在这里仍然遇到了一个小问题。为什么我必须先填充变量数组才能使用它?在这种情况下,我必须输入 arraynya arr_id_p_dtl := arr_id_p_dtl(0,0,0,0,0,0,0,0,0,0,0,0,0); 而不是 arraynya arr_id_p_dtl := arr_id_p_dtl(); 否则,它会抛出“超出计数”错误:(
    如果我有一个 100 长度的可变数组,那将是可怕的吗?
  • @thekucays - 不确定我是否理解您的问题。我很难想象我会首先使用varray 而不是嵌套表或关联数组的情况。如果您出于某种原因要声明 100 个元素 varray 并希望将每个元素初始化为 0,我只需编写我在答案中所做的循环并以这种方式初始化元素。
猜你喜欢
  • 2016-02-25
  • 2010-12-24
  • 2011-01-04
  • 1970-01-01
  • 2011-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-31
相关资源
最近更新 更多