Oracle 精确获取返回的行数超过过程中请求的行数

Oracle 精确获取返回的行数超过过程中请求的行数,oracle,plsql,Oracle,Plsql,当嵌套表包含多个值时,调用后过程get Down错误 是否可以将新的_ID变量放入所有块或其他解决方案中 ORA-01422:精确获取返回的行数超过请求的行数 procedure EMP_INSERT ( P_EMP employees_nt ) as NEW_ID number; begin FORALL i IN 1 .. P_EMP.COUNT Insert into test (val_1) values (P_EMP(i)) RETURNING

当嵌套表包含多个值时,调用后过程get Down错误

是否可以将新的_ID变量放入所有块或其他解决方案中

ORA-01422:精确获取返回的行数超过请求的行数

procedure EMP_INSERT (
    P_EMP employees_nt
)
as
   NEW_ID number;

begin

   FORALL i IN 1 .. P_EMP.COUNT
        Insert into test (val_1) values (P_EMP(i)) RETURNING new_id into NEW_ID;
        Insert into test2 (val_2) values (NEW_ID);   
        //Is it possible put here NEW_ID to null?

end;    
    
    

由于是批量插入,因此必须批量返回第一个FORALL的值。然后,您可以使用它们执行另一个FORALL,以插入到第二个表中

drop table t2;
drop table t;
drop sequence t2_seq;
drop sequence t_seq;

create sequence t_seq start with 100;
create sequence t2_seq;
create table t (
       t_id  number default t_seq.nextval not null,
       val_1 varchar2(10)
);
create table t2 (
       t2_id number default t2_seq.nextval not null,
       t_id  number);
declare
  type t_val_tab is table of t.val_1%type;
  type t_id_tab is table of t.t_id%type;
  
  l_val_tab t_val_tab := t_val_tab();
  l_id_tab t_id_tab;
begin
  l_val_tab.extend(3);
  l_val_tab(1) := 'a';
  l_val_tab(2) := 'b';
  l_val_tab(3) := 'c';
  
  forall i in l_val_tab.first .. l_val_tab.last
  insert into t(val_1) values (l_val_tab(i))
  returning t.t_id bulk collect into l_id_tab;
  
  forall i in l_id_tab.first .. l_id_tab.last
  insert into t2(t_id) values (l_id_tab(i));
end;
/

select * from t2;
/*
t2  t
1   100
2   101
3   102
*/

由于是批量插入,因此必须批量返回第一个FORALL的值。然后,您可以使用它们执行另一个FORALL,以插入到第二个表中

drop table t2;
drop table t;
drop sequence t2_seq;
drop sequence t_seq;

create sequence t_seq start with 100;
create sequence t2_seq;
create table t (
       t_id  number default t_seq.nextval not null,
       val_1 varchar2(10)
);
create table t2 (
       t2_id number default t2_seq.nextval not null,
       t_id  number);
declare
  type t_val_tab is table of t.val_1%type;
  type t_id_tab is table of t.t_id%type;
  
  l_val_tab t_val_tab := t_val_tab();
  l_id_tab t_id_tab;
begin
  l_val_tab.extend(3);
  l_val_tab(1) := 'a';
  l_val_tab(2) := 'b';
  l_val_tab(3) := 'c';
  
  forall i in l_val_tab.first .. l_val_tab.last
  insert into t(val_1) values (l_val_tab(i))
  returning t.t_id bulk collect into l_id_tab;
  
  forall i in l_id_tab.first .. l_id_tab.last
  insert into t2(t_id) values (l_id_tab(i));
end;
/

select * from t2;
/*
t2  t
1   100
2   101
3   102
*/

集合p_EMP包含多行,导致Returning子句返回多行,但您正在尝试以标量形式返回它们。你不能那样做。您需要创建一个集合并返回到该集合中

create type  new_id_list_nt is table of integer;
create or replace 
procedure emp_insert ( p_emp employees_nt ) 
as
   new_id_array new_id_list_nt; 
begin
    forall i in indices of p_emp
          insert into test1(val_1) values(p_emp(i)) 
          returning t1_id bulk collect into new_id_array; 

        
   insert into test2 (val_2) 
        select column_value 
          from table(new_id_array);   
    
end emp_insert;
用于返回到的集合必须在架构级别或包中定义。如果是本地定义的,则不能通过SQL进行引用。看

注:我使用的索引不是“1..p_emp.count”。这是因为过程无法知道集合是“1..”所要求的密集集合(即不缺少索引值),“的索引”可以正确处理稀疏集合

您可能希望尝试的内容:而不是Forall使用TABLE函数进行插入,就像在第二次插入中所做的那样。

您的集合p\u EMP包含多行,导致Returning子句返回多行,但您正在尝试以标量形式返回它们。你不能那样做。您需要创建一个集合并返回到该集合中

create type  new_id_list_nt is table of integer;
create or replace 
procedure emp_insert ( p_emp employees_nt ) 
as
   new_id_array new_id_list_nt; 
begin
    forall i in indices of p_emp
          insert into test1(val_1) values(p_emp(i)) 
          returning t1_id bulk collect into new_id_array; 

        
   insert into test2 (val_2) 
        select column_value 
          from table(new_id_array);   
    
end emp_insert;
用于返回到的集合必须在架构级别或包中定义。如果是本地定义的,则不能通过SQL进行引用。看

注:我使用的索引不是“1..p_emp.count”。这是因为过程无法知道集合是“1..”所要求的密集集合(即不缺少索引值),“的索引”可以正确处理稀疏集合

您可能希望尝试的内容:而不是Forall使用表函数进行插入,就像在第二次插入中所做的那样。

您在测试表中插入的值是什么<代码>P_EMP(i)。???您可以将NEW_ID设置为null。@AnkitBajpai在测试表I中插入1或2,但在测试2中,我插入了表testAssuming
test中第一次插入的返回值。NEW_ID
正在由序列填充?@Kevin Seymour,是序列生成ID(主键)!我已经发布了一个答案,但在未来,您必须包括一个最小的可复制示例,或者至少从一些DDL、DML开始:提出明确问题的责任在您身上,而不是在您寻求帮助的人身上。您在测试表中插入了什么值<代码>P_EMP(i)。???您可以将NEW_ID设置为null。@AnkitBajpai在测试表I中插入1或2,但在测试2中,我插入了表testAssuming
test中第一次插入的返回值。NEW_ID
正在由序列填充?@Kevin Seymour,是序列生成ID(主键)!我已经发布了一个答案,但在未来,你必须包括一个最小的可复制示例,或者至少从一些DDL、DML开始:提出明确问题的责任在于你,而不是那些你正在寻求帮助的人。