繁体   English   中英

在表中插入数据,在一个查询中用FK更新其他表

[英]Insert data in table, update other table with FK in one query

我有一个具有3个属性的表A:

ID(PK),UNIT(varchar2),VALUE(数字)

我还有另一个表B,它通过外键引用表A的PK。

ID,FK_TABLE_A

表B中已经有记录,但是属性FK_TABLE_A的值为空。 我想要的是,通过向表A中插入新数据并将新创建的主键作为外键引用到表B中,表B中的所有记录都获得了对表A PK 的唯一引用

到目前为止,我已经完成了什么:现在可以通过以下SQL插入新数据:

INSERT INTO TABLE_A(ID, UNIT, VALUE) VALUES (TABKE_A_SEQ.nextval, 'SOME_STRING', 1);

我可以手动更新对表B的引用

UPDATE TABLE_B SET FK_TABLE_A = 123; //123 is just an example PK

但是我不想每次DB都查询每个记录,而是想以某种方式将第一个insert与第二个update结合在一起。 这样更新就可以参考表A中新创建的PK。

这可能吗?

我正在使用Oracle作为数据库。

在会话中使用了序列后,可以使用currval伪列通过上一个nextval调用来获取会话中发布的最后一个序列值:

INSERT INTO TABLE_A(ID, UNIT, VALUE) VALUES (TABKE_A_SEQ.nextval, 'SOME_STRING', 1);
UPDATE TABLE_B SET FK_TABLE_A = TABKE_A_SEQ.currval;

(尽管您没有过滤器,但会将表B中的所有行更新为相同的FK值;想必您正在做一些复杂的事情来标识相关行...)


如果您想要一对一的关系,而不关心哪一行获得哪个PK值,并且可以使约束可延期,则可以采用其他方法。 使用序列更新表B的所有行,然后使用这些表创建表A的行。

使用快速演示表:

create table table_a (id number primary key, unit varchar2(20), value number);
create table table_b (id number,
  fk_table_a number references table_a(id) initially deferred deferrable);
create sequence table_a_seq;
create sequence table_b_seq start with 50;

insert into table_b (id) select table_b_seq.nextval from dual connect by level <= 5;

然后,在单个事务中,更新所有行并进行一次插入:

update table_b set fk_table_a = table_a_seq.nextval;

insert into table_a (id, unit, value)
select fk_table_a, 'SOME_STRING', 1
from table_b;

约束必须是可延迟的,以允许更新首先发生; 否则,您会得到ORA-02291。

如果单位/值来自table_a ,则可以在查询中包括这些单位/值,而不必使用固定文字。 很难说出您实际需要的东西,并且您说它们甚至可能为空。

现在您有了:

select * from table_a;

        ID UNIT                      VALUE
---------- -------------------- ----------
         1 SOME_STRING                   1
         2 SOME_STRING                   1
         3 SOME_STRING                   1
         4 SOME_STRING                   1
         5 SOME_STRING                   1

select * from table_b;

        ID FK_TABLE_A
---------- ----------
        50          1
        51          2
        52          3
        53          4
        54          5

使用触发器(在TABLE_A上)在TABLE_B中创建行。

例如(假设您正在使用SEQUENCE生成PK)

 CREATE OR REPLACE TRIGGER TR_TABLE_A_AI
 AFTER INSERT
 ON TABLE_A
 FOR EACH ROW
BEGIN
  INSERT INTO TABLE_B VALUES (SEQ_TABLE_B.NEXTVAL, :NEW.ID);
END;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM