Oracle将一个表的数据与另一个表同步

时间:2019-12-28 19:28:25

标签: sql oracle

我有两个表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查询?

3 个答案:

答案 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;