我有两个表Table 1和Table 2,两个表都有唯一的ID。表1具有表2 id作为外键。
表1
id table2 id
---------------
1 NULL
2 NULL
表2
id date
---------------
1 '28/12/2019'
2 '30/12/2019'
每次将新日期添加到表2日期并与表1数据同步时,要运行什么SQL查询?
答案 0 :(得分:1)
以下示例可能会有所帮助(Oracle 18c)。想法:{1}将表与MERGE同步。 {2}使用用于插入两个表的过程。
测试表
-- parent (always use DATE for dates!)
create table table2 ( id primary key, date_ )
as
select 1, to_date( '28/12/2019', 'DD/MM/YYYY' ) from dual union all
select 2, to_date( '30/12/2019', 'DD/MM/YYYY' ) from dual ;
-- child
create table table1 (
id number generated always as identity start with 5000 primary key
, table2id number references table2( id ) not null unique
) ;
-- the 2 tables contain the following data:
SQL> select * from table2 ;
ID DATE_
---------- ---------
1 28-DEC-19
2 30-DEC-19
SQL> select * from table1 ;
no rows selected
{1}合并
-- initial sync (P)arent <-> (C)hild
merge into table1 C
using table2 P on ( C.table2id = P.id )
when not matched then
insert ( C.table2id ) values ( P.id ) ;
-- 2 rows merged.
-- data
SQL> select * from table2 ;
ID DATE_
---------- ---------
1 28-DEC-19
2 30-DEC-19
SQL> select * from table1 ;
ID TABLE2ID
---------- ----------
5000 1
5001 2
{2}程序
-- assumption: ("parent" table) table2 id generated by a sequence
-- sequence: use nextval and currval.
create sequence t2seq start with 2000 increment by 1 ;
create or replace procedure insert2 ( dt_ date )
is
begin
insert into table2 ( id, date_ ) values ( t2seq.nextval, dt_ ) ;
insert into table1 ( table2id ) values ( t2seq.currval ) ;
end ;
/
{3}测试
begin
for i in 100 .. 105
loop
insert2( sysdate + i ) ; -- call the procedure, insert some dates
end loop;
commit ;
end ;
-- check:
SQL> select * from table1 ;
ID TABLE2ID
---------- ----------
5000 1
5001 2
5002 2000
5003 2001
5004 2002
5005 2003
5006 2004
5007 2005
8 rows selected.
SQL> select * from table2 ;
ID DATE_
---------- ---------
1 28-DEC-19
2 30-DEC-19
2000 07-APR-20
2001 08-APR-20
2002 09-APR-20
2003 10-APR-20
2004 11-APR-20
2005 12-APR-20
8 rows selected.
{4}尝试再次同步->合并0行。
merge into table1 C using table2 P on ( C.table2id = P.id )
when not matched then
insert ( C.table2id ) values ( P.id ) ;
0 rows merged.
DBfiddle here. NEXTVAL和CURRVAL文档here。
答案 1 :(得分:0)
如果仅希望在创建表2中的记录时将记录插入表1中,我建议在表2上的插入触发器之后添加。这是显示该触发器的代码的链接。他们使用带有订单审核表的订单表示例来跟踪订单更改。
https://www.techonthenet.com/oracle/triggers/after_insert.php
上面链接中的后触发示例。
parser = etree.XMLParser(remove_blank_text=True)
titlovi = etree.parse('titlovi.xml', parser).getroot()
b = etree.SubElement(titlovi[1][0], 'movie').set('title', title)
c = etree.SubElement(b, 'imdb_id').text = imdb_id
with open('titlovi.xml', 'wb') as file:
file.write(etree.tostring(titlovi, pretty_print=True))
答案 2 :(得分:0)
我假设您在这两个表之间具有OneToOne关系,并且您要使审核记录与主记录分开。在这种情况下:
所以一种方法是将触发器添加到table2中。
请记住,在同一会话中您将获得相同的序列CURRVAL
。这两个表共享序列值
CREATE OR REPLACE TRIGGER TRIGGER1
BEFORE INSERT ON TABLE_2
FOR EACH ROW
WHEN (new.ID IS NULL)
BEGIN
:new.ID := TABLE_SEQ.NEXTVAL;
INSERT INTO TABLE_1(ID,TABLE2_ID) VALUES(TABLE_SEQ.CURRVAL,TABLE_SEQ.CURRVAL);
END;
您还需要一个序列。
CREATE SEQUENCE TABLE_SEQ
START WITH 1
INCREMENT BY 1;