【问题标题】:Using the same Oracle Sequence while loading 2 tables using SQLLDR使用 SQLLDR 加载 2 个表时使用相同的 Oracle 序列
【发布时间】:2020-02-05 23:15:19
【问题描述】:

我想使用 SQLLDR 加载以下 2 个表。 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(最后一列的值1是虚拟的,因为我想生成Oracle Sequence(partnersequence) Number

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】:

编辑:我误解了 OP 的问题。他正在寻找一种解决方案,让两个表的每行都获得相同的序列号(我相信在 cmets 中得到了回答)。这个答案显示了如何在整个负载中获得一个唯一的序列。虽然不是答案,但我认为这些信息会有所帮助,所以我会留下它。

正如您已经发现的那样,在控制文件中调用您的 sequence.nextval 会导致它随着加载的每一行而递增。诀窍是调用一个包,在实例化时设置一次值,然后调用包函数返回加载的每一行的值。由于我已经为我的负载设置了这个,我将与你分享我所做的解释。我们的加载将 load_date 和 load_sequence_id 添加到表中,这就是您将在这些示例中看到的内容。假设读者已经理解了包的结构,因为在此处解释太多,而不混淆主要问题。

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

因此,在开始加载时,当要加载的第一行调用函数获取序列时,将实例化包并设置日期和序列,然后返回。只要会话处于活动状态,从那时起日期/顺序就不会改变,随后对 getter 函数的调用将继续返回相同的值。

包装规格和正文:

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""

【讨论】:

  • 非常感谢您的建议,Gary...让我合并并测试它...
  • Gary,如果我不清楚我的要求,我很抱歉。我想为每条记录创建一个新序列#(而不是整个会话)。因此,对于给定的行(在数据文件中),Customer 和 Customer_contact 表将使用序列 #(比如 1001)。在处理下一条记录(来自数据文件)时,将使用下一个序列#(1002)。请你在这里帮忙...
  • 。本质上,我想为 2 个表(Customer 和 Customer_contact)使用生成的序列号,因为序列号是 Customer 表中的唯一键,同样是 Customer_contact 表中的外键
  • 天啊!在这种情况下,我认为您可以将合作伙伴序列.currval(当前值)用于 Customer_contact 表。我没有测试这个。如果这对您有用,请报告。
  • 再次感谢您的建议,加里。欣赏它......我使用它(这是我的第一个想法)。但是,由于我一次迁移一家公司(存储在客户中)以进行生产,因此如果在当前公司的迁移正在进行时(为不同的公司)创建客户,则 Currval 可能会不同。
猜你喜欢
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
  • 2021-08-18
  • 1970-01-01
  • 2012-09-13
相关资源
最近更新 更多