是否可以 return Insert as select 语句中的主键 - Oracle?
Is it possible to return the Primary Key on an Insert as select statement - Oracle?
所以我通常在使用触发器时获取新插入记录的主键如下。
insert into table1 (pk1, notes) values (null, "Tester") returning pk1
into v_item;
我正在尝试使用相同的概念,但使用 select 语句进行插入。例如:
insert into table1 (pk1, notes) select null, description from table2 where pk2 = 2 returning pk1
into v_item;
注意:
1. table1 上有一个触发器,它会在插入时自动创建一个 pk1。
2. 由于要插入的 table 的大小,我需要使用 select 插入。
3.插入基本上是记录的复制,所以一次只插入1条记录。
如果我可以提供更多信息,请告诉我。
我不相信你可以直接用 insert/select 做到这一点。但是,您可以使用 PL/SQL 和 FORALL 来完成。考虑到 table 大小的限制,您必须使用 l_limit
来平衡内存使用和性能。这是一个例子...
鉴于此 table 有 100 行:
create table t (
c number generated by default as identity,
c2 number
);
insert into t (c2)
select rownum
from dual
connect by rownum <= 100;
你可以这样做:
declare
cursor t_cur
is
select c2
from t;
type t_ntt is table of number;
l_c2_vals_in t_ntt;
l_c_vals_out t_ntt;
l_limit number := 10;
begin
open t_cur;
loop
fetch t_cur bulk collect into l_c2_vals_in limit l_limit;
forall i in indices of l_c2_vals_in
insert into t (c2) values (l_c2_vals_in(i))
returning c bulk collect into l_c_vals_out;
-- You have access to the new ids here
dbms_output.put_line(l_c_vals_out.count);
exit when l_c2_vals_in.count < l_limit;
end loop;
close t_cur;
end;
你不能使用那个机制; as shown in the documentation 铁路图:
返回子句只允许在值版本中使用,不能在子查询版本中使用。
我将您的第二个限制(大约 'table size')解释为您必须处理的列数,可能是单个变量,而不是行数 - 我不知道看看这与这里有什么关系。不过,有一些方法可以避免每列有很多局部变量;你可以先 select 到行类型变量中:
declare
v_item number;
v_row table1%rowtype;
begin
...
select null, description
into v_row
from table2 where pk2 = 2;
insert into table1 values v_row returning pk1 into v_item;
dbms_output.put_line(v_item);
...
或使用循环,如果您真的只有一行,这可能会使事情看起来比必要的更复杂:
declare
v_item number;
begin
...
for r in (
select description
from table2 where pk2 = 2
)
loop
insert into table1 (notes) values (r.description) returning pk1 into v_item;
dbms_output.put_line(v_item);
...
end loop;
...
或与一个集合...正如@Dan 在我回答这个问题时发布的那样,所以我不会重复! - 虽然对于单行来说这可能有点矫枉过正或过于复杂。
所以我通常在使用触发器时获取新插入记录的主键如下。
insert into table1 (pk1, notes) values (null, "Tester") returning pk1 into v_item;
我正在尝试使用相同的概念,但使用 select 语句进行插入。例如:
insert into table1 (pk1, notes) select null, description from table2 where pk2 = 2 returning pk1 into v_item;
注意:
1. table1 上有一个触发器,它会在插入时自动创建一个 pk1。
2. 由于要插入的 table 的大小,我需要使用 select 插入。
3.插入基本上是记录的复制,所以一次只插入1条记录。
如果我可以提供更多信息,请告诉我。
我不相信你可以直接用 insert/select 做到这一点。但是,您可以使用 PL/SQL 和 FORALL 来完成。考虑到 table 大小的限制,您必须使用 l_limit
来平衡内存使用和性能。这是一个例子...
鉴于此 table 有 100 行:
create table t (
c number generated by default as identity,
c2 number
);
insert into t (c2)
select rownum
from dual
connect by rownum <= 100;
你可以这样做:
declare
cursor t_cur
is
select c2
from t;
type t_ntt is table of number;
l_c2_vals_in t_ntt;
l_c_vals_out t_ntt;
l_limit number := 10;
begin
open t_cur;
loop
fetch t_cur bulk collect into l_c2_vals_in limit l_limit;
forall i in indices of l_c2_vals_in
insert into t (c2) values (l_c2_vals_in(i))
returning c bulk collect into l_c_vals_out;
-- You have access to the new ids here
dbms_output.put_line(l_c_vals_out.count);
exit when l_c2_vals_in.count < l_limit;
end loop;
close t_cur;
end;
你不能使用那个机制; as shown in the documentation 铁路图:
返回子句只允许在值版本中使用,不能在子查询版本中使用。
我将您的第二个限制(大约 'table size')解释为您必须处理的列数,可能是单个变量,而不是行数 - 我不知道看看这与这里有什么关系。不过,有一些方法可以避免每列有很多局部变量;你可以先 select 到行类型变量中:
declare
v_item number;
v_row table1%rowtype;
begin
...
select null, description
into v_row
from table2 where pk2 = 2;
insert into table1 values v_row returning pk1 into v_item;
dbms_output.put_line(v_item);
...
或使用循环,如果您真的只有一行,这可能会使事情看起来比必要的更复杂:
declare
v_item number;
begin
...
for r in (
select description
from table2 where pk2 = 2
)
loop
insert into table1 (notes) values (r.description) returning pk1 into v_item;
dbms_output.put_line(v_item);
...
end loop;
...
或与一个集合...正如@Dan 在我回答这个问题时发布的那样,所以我不会重复! - 虽然对于单行来说这可能有点矫枉过正或过于复杂。