在使用SQLLDR加载2个表时使用相同的Oracle序列

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

我想使用SQLLDR加载以下2个表。这两个表的表结构如下:

CREATE TABLE Customer
(ID varchar2(50), --PK
org_cd  varchar2(50), --PK
NAME VARCHAR2 (255),
Address1 VARCHAR2(1000),
DOB TIMESTAMP(3),
cust_ref_col number  ---used for all the future references to this record since this is a number. This is unique key.
    );

CREATE TABLE Customer_contact
(ID varchar2(50), --PK
org_cd  varchar2(50), --PK 
Contact_id Number, --PK --Running serial # for a given Customer
contact_name varchar2(50),
cust_ref_col number  ---foreign key from Customer table 
);

这里是数据文件customer.dat(由于我要生成Oracle序列号(partnersequence),所以最后一列的值是虚拟的

PTNR_78814824,ACCT,Tom,123 Church Road, 12-dec-99,1,Ralph,1
PTNR_78814825,FIN,Tom,124 Main Road, 12-dec-99,2,Jody,1
PTNR_78814826,ENGG,Tom,125 Station Road, 12-dec-99,3,Mardy,1

我的控制文件看起来像这样

LOAD DATA
INFILE test.dat
INTO TABLE Customer
APPEND
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS
(ID   ,
 org_cd   ,
 name     ,
 Address1 ,
 DOB      ,
 cust_ref_col   "partnersequence.nextval"
 )

INTO TABLE Customer_contact
APPEND
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS
(ID   ,
 org_cd   ,
 Fill1 Filler,
 Fill2 Filler,
 Fill3 Filler,
 Fill4 Filler,
 cust_ref_col   "partnersequence.nextval"
)

这里的问题是,Customer_contact表中的cust_ref_col正在获取新序列#。我想使用为生成的相同序列客户表。您能帮忙吗?

sql-loader
1个回答
0
投票
正如您已经发现的那样,在控制文件中调用sequence.nextval会使它在加载的每一行中递增。诀窍是调用一个在实例化后立即设置值的包,然后调用返回每个加载行的值的包函数。由于我已经为自己的负载进行了设置,因此我将与您分享我所做的解释。我们的加载将load_date和load_sequence_id添加到表中,因此您将在这些示例中看到这些内容。假设读者已经理解了软件包的结构,因为在这里不解释主要问题就太多了,无法解释。

您需要创建一个序列(已经创建)和一个包。该程序包包含2个变量来保存load_date和load_seq_id,2个“ getter”函数返回它们,并在实例化时进行设置。然后,您的控制文件将调用“ getter”函数以从包中返回load_date和load_seq_id,每行都将相同。

包装规格和主体:

CREATE OR REPLACE PACKAGE SCHEMA.LOAD_SEQ AS /****************************************************************************** NAME: LOAD_SEQ PURPOSE: Sets unique load_date and Load_seq_id per session when the package is instantiated. Package functions are intended to be called from control files so all rows in a file load will have the same load_date and load_seq_id. When the functions are called, the package is instantiated and the code at the bottom is run once for the session, setting the load_date and load_seq_id. The functions simply return the values which will remain the same for that session. load_date date "MM/DD/YYYY" "to_char(trunc(schema.load_seq.get_load_date), 'mm/dd/yyyy')", load_seq_id decimal external "schema.load_seq.get_load_seq_id" (each row then has the same load_seq_id). REVISIONS: Ver Date Author Description --------- ---------- --------------- ------------------------------------ 1.0 2/20/2017 Gary_W 1. Created this package. ******************************************************************************/ NEXT_LOAD_SEQ_ID NUMBER; NEXT_LOAD_DATE DATE; FUNCTION GET_LOAD_SEQ_ID RETURN NUMBER; FUNCTION GET_LOAD_DATE RETURN DATE; END THC_LOAD_SEQ; / CREATE OR REPLACE PACKAGE BODY SCHEMA.LOAD_SEQ AS /****************************************************************************** NAME: GET_LOAD_SEQ_ID PURPOSE: Return the package variable LOAD_SEQ.NEXT_LOAD_SEQ_ID which is set when the package is instantiated. It does not change during the session. REVISIONS: Ver Date Author Description --------- ---------- --------------- ------------------------------------ 1.0 2/20/2017 Gary_W 1. Created this package. ******************************************************************************/ FUNCTION GET_LOAD_SEQ_ID RETURN NUMBER IS BEGIN RETURN LOAD_SEQ.NEXT_LOAD_SEQ_ID; END GET_LOAD_SEQ_ID; /****************************************************************************** NAME: GET_LOAD_DATE PURPOSE: Return the package variable LOAD_SEQ.NEXT_LOAD_DATE which is set when the package is instantiated. It does not change during the session. REVISIONS: Ver Date Author Description --------- ---------- --------------- ------------------------------------ 1.0 2/20/2017 Gary_W 1. Created this package. ******************************************************************************/ FUNCTION GET_LOAD_DATE RETURN DATE IS BEGIN RETURN LOAD_SEQ.NEXT_LOAD_DATE; END GET_LOAD_DATE; BEGIN -- Code outside of the procedures/functions defined in the spec runs -- once on instantiation of the package, when the package is first called by the session. -- It sets the package variables which then do not change during the life of the session. SELECT SYSDATE, partnersequence.NEXTVAL INTO LOAD_SEQ.NEXT_LOAD_DATE, LOAD_SEQ.NEXT_LOAD_SEQ_ID FROM DUAL; END LOAD_SEQ; /

在您的控制文件中:

LOAD_DATE date "MM/DD/YYYY" "to_char(trunc(schema.load_seq.get_load_date), 'mm/dd/yyyy')" cust_ref_col "decimal external "schema.load_seq.get_load_seq_id""

© www.soinside.com 2019 - 2024. All rights reserved.