尝试在“插入”之后将 ID(由触发器/序列生成)返回给变量
Posted
技术标签:
【中文标题】尝试在“插入”之后将 ID(由触发器/序列生成)返回给变量【英文标题】:Trying to get a ID (generated by a trigger/sequence) returned to a variable after a 'Insert into' 【发布时间】:2018-06-19 18:41:15 【问题描述】:我目前在 VALUE 表上设置了一个触发器(带有序列),每次将一行插入表中时,它都会自动生成一个新的 value_id。我正在尝试将新的 value_id(由触发器/序列生成)返回到变量中,以便稍后在 proc 中插入关系表中使用它。
但是,当我使用returning
语句时,Oracle 会返回错误。当我使用传统的插入时,代码似乎运行/编译得很好。
你知道我做错了什么吗?以下是我编写的代码的精简版:
insert into value
(value_id,
energy_product_id,
data_source_id,
unit_cd,
value_tx,
hr
)
select null,
energy_product_id,
data_source_id,
unit_cd,
value_tx
from value
returning value_id into v_value_id;
提前致谢
**编辑:** 下面是讨论过的更改的代码。但是它会出错:
insert into value
(value_id,
energy_product_id,
data_source_id,
unit_cd,
value_tx,
hr
)
select (select seq_sample.nextval from dual),
energy_product_id,
data_source_id,
unit_cd,
value_tx
from value
returning value_id into v_value_id;
【问题讨论】:
什么Oracle版本?请发一个minimal reproducible example你不是使用序列来生成值吗? 11.2.0 。我正在使用序列/触发器来生成值。但我需要将该值返回到一个变量中,以便稍后在另一个插入中使用它。 @OldProgrammer 我编辑了我的问题,感谢您的提醒。我是否按照该链接中的说明进行了正确的编辑? 所以不是触发器,而是在过程中获取 seq.nextval,然后您可以传递到多个插入中。 那将是不正确的,因为那样我会在我插入的值之后获得下一个值。我需要那个确切的值。例如:(1st Table) Value_ID (1) Value_TX(5) --- (2nd Table) Value_ID(1) Translation_ID(1) CREATE_DT(sysdate)。我需要'1' value_id 显示在两个表/插入中 【参考方案1】:如果您的插入有 values (...)
子句,您似乎只能使用 returning into
子句,而不是在使用查询时。
您可以使用集合代替:
declare
type t_rows is table of value_table%rowtype;
v_rows t_rows;
begin
select seq_sample.nextval,
energy_product_id,
data_source_id,
unit_cd,
value_tx, hr
bulk collect into v_rows
from value_table;
forall i in 1..v_rows.count
insert into value_table values v_rows(i);
-- just as debug to see new ID values
for i in 1..v_rows.count loop
dbms_output.put_line(v_rows(i).value_id);
end loop;
end;
/
如果您想保留触发器并且它会覆盖任何传入的值 - 这是正常的,但是这可能是一个例外情况 - 那么您可以使用第二个集合来取回 ID,带有批量收集返回子句:
declare
type t_rows is table of value_table%rowtype;
v_rows t_rows;
type t_ids is table of number;
v_ids t_ids;
begin
select null,
energy_product_id,
data_source_id,
unit_cd,
value_tx, hr
bulk collect into v_rows
from value_table;
forall i in 1..v_rows.count
insert into value_table values v_rows(i)
returning value_id bulk collect into v_ids;
-- just as debug to see new ID values
for i in 1..v_ids.count loop
dbms_output.put_line(v_ids(i));
end loop;
end;
/
ID 的索引应该与其他行数据的索引对应,因此您可以更新原始集合:
for i in 1..v_rows.count loop
v_rows(i).value_id := v_ids(i);
end loop;
但我不确定这是否得到保证。它似乎应该,但我不记得看到它记录在案。
似乎应该有一个更直接的机制来实现这一点......
【讨论】:
【参考方案2】:我最近发布了一个关于 Insert into return 的工作的问题,我相信 @APC 提供的答案将适用于你提到触发器将覆盖 https://***.com/a/50892580/7071906 分配值的情况,尝试类似
declare
select CURSOR c1 IS
SELECT 1 val,energy_product_id,data_source_id,unit_cd,value_tx from
value
lrec c1%rowtype;
ldata c1%rowtype;
id number;
begin
fetch c1 into lrec
ldata.value_id := lrec.id;
ldata.energy_product_id := lrec.energy_product_id;
ldata.unit_cd := lrec.unit_cd;
ldata.value_tx := lrec.value_tx;
INSERT INTO my_table
VALUES ldata
RETURNING val1 INTO id;
end;
How does Oracle Insert Into work when order of values is not defined?
【讨论】:
谢谢,是的,我可以让传统的插入工作,但不能插入到 select from 中以返回任何内容......(如果有意义的话) 在这种情况下,这个***线程link已经为您的问题指出了解决方案,看起来正是您要问的) 啊...谢谢@prakriti,看来我要问的是不可能的:(以上是关于尝试在“插入”之后将 ID(由触发器/序列生成)返回给变量的主要内容,如果未能解决你的问题,请参考以下文章