2010-09-21 52 views
3

假设你有一个表:可以将变量传递给SQL * Loader控制文件吗?

CREATE TABLE Customer 
(
    batch_id   NUMBER, 
    customer_name VARCHAR2(20), 
    customer_address VARCHAR2(100) 
) 

而且假设你有一个控制文件来填充这个表:

 
LOAD DATA INFILE 'customers.dat' 
REPLACE 

INTO TABLE Customer 
(
    batch_id   ??????, 
    customer_name POSITION(001:020), 
    customer_address POSITION(021:120) 
) 

是否有可能为batch_id的值传递给我的控制文件,当我运行使用SQL * Loader?例如,是否可以指定绑定变量(将问号转为:MY_AWESOME_BATCH_ID)?

回答

7

一个相对简单的归档方法是创建一个存储函数,该函数返回批处理编号并在加载器文件中使用它。

create or replace function getBatchNumber return number as 
begin 
    return 815; 
end; 
/

LOAD DATA INFILE 'customers.dat' 
REPLACE 

INTO TABLE Customer 
(
    batch_id   "getBatchNumber", 
    customer_name POSITION(001:020), 
    customer_address POSITION(021:120) 
) 
+0

不错。如果您希望函数为Loader的每次运行执行一个新的批处理,请将其放入一个包中,并使其返回一个包变量,该变量在第一次调用时将被初始化(例如,按顺序)。 – 2010-09-22 13:21:40

+0

在启动sqlloader之前,您可能还决定在脚本中实时重新创建函数。 – 2010-09-22 14:00:25

2

不容易,如果我记得没错,但这里有几个选择:

  • 如果只有将是一个进程中运行SQL 装载机的时间,使用空值或一个固定的值,然后运行SQL Plus脚本作为此后流程的一部分,以更新序列值。
  • 调用一个脚本,该脚本将抓取您的批次ID的下一个序列值,然后将控制文件(包括batch_id常量)移出。
1

如果这是可以接受的,通过增加对每个负载自动生成BATCH_ID值,超过这个工作对我来说。样本中的10分钟间隔需要根据具体负载进行调整 - 要准确,负载必须在指定的时间间隔内完成,并且下一次负载不得在小于指定时间的时间内开始。

一个缺点是,它在大批量上显着减速 - 这是在每条生产线上运行MAX汇总的价格。

LOAD DATA 
... 
INTO TABLE XYZ 
(
... 
BATCH_ID expression "(select nvl(max(batch_id) + 1, 1) from extra_instruments_party_to where create_date < (sysdate - interval '10' minute))", 
CREATE_DATE SYSDATE 
) 
+0

有趣的方法。也可以创建一个序列,在控制文件中使用它,然后删除它。 – Glenn 2012-06-21 00:56:04

+0

除非我错过了这个想法,否则我认为该序列不适用于此目的 - 我们需要一组记录的ID,而不是每个记录;序列会在每个插入中增加。 – 2012-06-22 16:19:35

相关问题