在SQL加载程序的列中传递变量

时间:2018-08-29 13:51:23

标签: oracle11g sql-loader

是否有一种使用SQL加载程序控制文件通过变量传递列的默认值的方法。 我想将默认值传递给Oracle表列,但不想对其进行硬编码。我可以使用可以根据需要更改的变量传递它吗?

谢谢。

2 个答案:

答案 0 :(得分:0)

否,您不能在命令行或环境中传递变量。没有command-line option来传递任意值,并且控制文件无法识别对环境变量的引用。

我认为,您能做的最好的事情就是有一个带有占位符的模板控制文件,您要在其中使用变量值,然后从模板生成您的实际控制文件,并在创建变量时替换您的变量(例如sed

假设您的表有3列和3列,为简单起见,您要为其中的两个设置默认值,一个字符串和一个数字。您可能有一个名为template.ctl的文件,其中包括:

...
fields terminated by ','
trailing nullcols
(
id,
col2 "nvl(:col2, '<DEFAULT_STR>')",
col3 "nvl(:col3, <DEFAULT_NUM>)"
)

然后在您的shell脚本中(现在对实际的默认值进行硬编码,因为您还没有说出它们的来源):

DEFAULT_STR="Some value"
DEFAULT_NUM=42

sed -e "s/<DEFAULT_STR>/${DEFAULT_STR}/" \
    -e "s/<DEFAULT_NUM>/${DEFAULT_NUM}/" \
    template.ctl > real.ctl

sqlldr usr/pwd control=real.ctl file=...

将生成real.ctl并替换为实际的默认值:

...
fields terminated by ','
trailing nullcols
(
id,
col2 "nvl(:col2, 'Some value')",
col3 "nvl(:col3, 42)"
)

因此,当您运行SQL * Loader时,它将使用这些默认值。

如果您可以同时运行多次,则可以使“真实”控制文件名唯一,例如通过附加当前的shell进程ID。


另一种选择是加载到允许为空的登台表,然后从登台表填充真实表-使用传递到SQL * Plus的位置参数,将空值的转换应用于此时的默认值,作为同一Shell脚本的一部分。

在您的Shell脚本中,调用SQL * Loader,但控制文件指向登台表:

sqlldr usr/pwd control=stage.ctl file=...

然后调用SQL * Plus,或者调用一个接受位置参数为默认值的脚本,或者调用内联命令,因为这相当简单。再说一遍,假设您的表有三列,为简单起见,您需要其中两列的默认值,一个字符串和一个数字的默认值:

DEFAULT_STR="Some value"
DEFAULT_NUM=42

sqlplus -l -s usr/pwd <<!EOF
whenever sqlerror exit failure rollback
insert into real_table (id, col2, col3)
select id, nvl(col2, '${DEFAULT_STR}'), nvl(col3, $DEFAULT_NUM)
from staging_table;
commit;
exit;
!EOF

(未经测试,但希望能给您要点!)

答案 1 :(得分:0)

  1. 创建$ sqlldr文件,并在每个$ {env_var}所处的​​位置使用唯一的唯一字符串。

例如,(通常,infile数据文件会发生变化), 因此,创建一个文件$ {standardFileName} _TEMPLATE.ctl 在该sqlldr TEMPLATE文件中,“ inflile”所在的行中,放置:

.Remove

(xxxxxxxx是不确定字符串)

  1. 然后从shell中执行以下操作:
    infile 'xxxxxxxx'               

这应该允许您运行一个sqlldr脚本,该脚本为每次通过选择一个特定的env_variables。