ORACLE使用SERIALIZABLE到PLSQL下载一致的数据。

问题描述 投票:0回答:1

为了从OLTP-数据库中下载一致的数据,使proc:

   procedure move_tables_to_mst_layer(v_sync sync_data) is
   pragma autonomous_transaction;
   v_src_table  varchar2(128);
   sql_stm      varchar2(30000);
   v_proc    varchar2(128);

begin

   execute immediate 'alter session SET ISOLATION_LEVEL = SERIALIZABLE';

   for rec in (select a_tbl_name as tblnm from a_tables
                where a_tbl_type in ('T0', 'T1')
                order by a_tbl_order
              )
   loop

       v_src_table := 'STG_'||rec.tblnm;
       sql_stm := 'insert /*+ append */ into '||v_src_table||' select t1.*
                    from '||rec.tblnm||' t1
                   where row_seq > '||v_sync.v_rowseq
                     ;
       --dbms_output.put_line(sql_stm);
       execute immediate sql_stm;
       --commit;
   end loop;

   commit;
   execute immediate 'alter session SET ISOLATION_LEVEL = READ COMMITTED';
exception
when others then
    errpck.raise_n_stop('SYNC', v_proc, 'Procedure move_tables_to_mst_layer');
end move_tables_to_mst_layer;

版本Oracle 12c.字段指示器 row_seq - 由trgger为每个表填充。对于任何DML操作(插入或更新):new.row_seq = seq_rowseq.nextavl, 其中seq_rowseq - 全局序列.周期性(每6-12小时一次)发生错误外键没有父表.这意味着什么过程从子表插入新记录而不是从父表插入新记录 - 我不知道它是如何发生的。可能是使用执行立即排除隔离级别可序列化?

oracle plsql serializable execute-immediate
1个回答
0
投票

我觉得你提供的信息不够多,谁也帮不了你。 表的结构是什么? 其他进程是否会向这些表插入? 表之间的FK关系是什么?

还有一点:在Oracle 12c及以上版本中,你绝对不应该使用触发器来填充序列中的一列。 触发器是性能良好的DML的敌人,12c中增加的IDENTITY功能否定了使用它们的理由。

网上已经有一些很好的文档。 我个人喜欢 这个 文章。

这是一个简单的例子,使用一个现有的序列(你有)。

CREATE SEQUENCE so_61439648_seq;

CREATE TABLE so_61439648 (
 some_id NUMBER,
 data_1 VARCHAR2(100),
 data_2 VARCHAR2(100)
);

ALTER TABLE so_61439648 MODIFY some_id DEFAULT so_61439648_seq.nextval;

下面是如何在创建表时设置它,但使用一个单独的序列。

CREATE SEQUENCE so_61439648_seq;

CREATE TABLE so_61439648 (
 some_id NUMBER DEFAULT so_61439648_seq.nextval,
 data_1 VARCHAR2(100),
 data_2 VARCHAR2(100)
);

你也可以把生成和附加序列的工作交给Oracle来做,但就我个人而言,出于同样的原因,即为你的约束条件取一个好听的名字,我喜欢上面的方法,因为它能使关系变得清晰。

下面是Oracle生成的方法。

CREATE TABLE so_61439648 (
 some_id NUMBER GENERATED ALWAYS AS IDENTITY,
 data_1 VARCHAR2(100),
 data_2 VARCHAR2(100)
);

SELECT t.data_default
  FROM all_tab_columns t
 WHERE t.table_name = 'SO_61439648'
   AND t.column_name = 'SOME_ID';
-- "ISEQ$$_1874517".nextval
© www.soinside.com 2019 - 2024. All rights reserved.