sqlldr - 如何将多个csv加载到多表

时间:2016-07-05 23:37:09

标签: sql-loader

第一个问题:我正在尝试将 test1.csv test2.csv test3.csv 加载到 table1 table2 table3 分别使用SQLLDR。如果知道这个领域,请不要理解我的缺点,在.ctl文件中定义这个时我无法做到这一点,只有我能想到的是下面的代码,但这不正确。所以我的问题是如何才能做到这一点或者这可能呢?

OPTIONS (SKIP=1)
LOAD DATA

INFILE 'test1.csv'
INFILE 'test2.csv'
INFILE 'test2.csv'

TRUNCATE

INTO TABLE table1
fields terminated by ',' optionally enclosed by '"'
TRAILING NULLCOLS
(
    Col1    "TRIM(:Col1)",
    Col2    "TRIM(:Col2)"
)


INTO TABLE table2
fields terminated by ',' optionally enclosed by '"'
TRAILING NULLCOLS
(
    Colx    "TRIM(:Colx)",
    Coly    "TRIM(:Coly)"
)


INTO TABLE table3
fields terminated by ',' optionally enclosed by '"'
TRAILING NULLCOLS
(
    Colp    "TRIM(:Colp)",
    Colq    "TRIM(:Colq)"
)

第二个问题:这是第一个问题的替代方案。由于我无法弄清楚第一个,我所做的是将每个表的负载拆分为多个.ctl文件,并在.bat文件中调用这三个文件。这至少有用,但我的问题是有一种方法来处理会话中的所有这3个.ctl文件而不提及用户/密码3次,如下所示?

sqlldr userid=user/pass@server control=test1.ctl
sqlldr userid=user/pass@server control=test2.ctl
sqlldr userid=user/pass@server control=test3.ctl

1 个答案:

答案 0 :(得分:0)

如果有一个可以使用的字段可以指示该文件的数据用于哪个表,则可以使用多个INFILE声明来执行此类操作。假设第一个字段是该指示符并且它不会被加载(将其定义为FILLER,因此sqlldr将忽略它):

...
INTO TABLE table1
WHEN (01) = 'TBL1'
fields terminated by ',' optionally enclosed by '"'
TRAILING NULLCOLS
(
    rec_skip filler POSITION(1),
    Col1    "TRIM(:Col1)",
    Col2    "TRIM(:Col2)"
)

INTO TABLE table2
WHEN (01) = 'TBL2'
fields terminated by ',' optionally enclosed by '"'
TRAILING NULLCOLS
(
    rec_skip filler POSITION(1),
    Colx    "TRIM(:Colx)",
    Coly    "TRIM(:Coly)"
)


INTO TABLE table3
WHEN (01) = 'TBL3'
fields terminated by ',' optionally enclosed by '"'
TRAILING NULLCOLS
(
    rec_skip filler POSITION(1),
    Colp    "TRIM(:Colp)",
    Colq    "TRIM(:Colq)"
)

逻辑上,每个INTO表WHEN部分处理每个文件。虽然并不那么灵活,但可能难以维持。为了便于维护,您可能只想拥有每个文件的控制文件?如果所有文件和表都是相同的布局,您也可以将它们全部加载到同一个临时表(带有指示符)以便于加载,然后以编程方式将它们拆分到单独的表中。该方法的优点是更快更容易加载,并且可以更好地控制拆分到过程的单独表格部分。只是其他一些想法。我已经完成了每种方法,取决于要求以及您能够改变的方式。