关于如何从查找表中填充 BOUNDFILLER 的任何想法?
你不能。(尽管文档中的措辞暗示您应该能够这样做;我认为这是一个文档错误,它应该说的更像是“不能将填充字段指定为另一个字段规范的 SQL 字符串的一部分,因为...”-然后例外 forBOUNDFILELR
更有意义)。
如果EMPID
不是数据文件中的字段,则不需要填充符。如果它在文件中但不在目标表中,则可以使用 plain 跳过它FILLER
,除非您以后也想引用该文件值。如果它是目标表中的列,那么您可以使用EXPRESSION
子句来进行查找,但是您不能在其他地方将其称为绑定变量。
如果您想在控制文件中的其他列的其他 SQL 表达式中引用它,那么您需要在这些列中重复查找作为子查询。
例如,您可以:
REFNBR BOUNDFILLER,
EMPID EXPRESSION "(SELECT EMPID FROM lookuptable WHERE REFNBR = :REFNBR)",
EMPFIRSTNAME EXPRESSION "(SELECT FIRST_NAME FROM anothertable WHERE empid = (SELECT EMPID FROM lookuptable WHERE REFNO = :REFNBR))",
...
或略带连接:
REFNBR BOUNDFILLER,
EMPID EXPRESSION "(SELECT EMPID FROM lookuptable WHERE REFNBR = :REFNBR)",
EMPFIRSTNAME EXPRESSION "(SELECT t1.FIRST_NAME FROM lookuptable t1 JOIN anothertable t2 ON t2.empid = t1.empid WHERE t1.REFNBR = :REFNBR)",
...
我已经将它们声明为EXPRESSION
假设它们在数据文件中没有相应的字段 - 本质上是为了这些目的,数据文件只有REFNBR
. (您可能还有其他未显示的字段;您甚至可能有与EMPID
您忽略的等相关的字段 - 但在这种情况下,我会将它们视为FILLER
并且无论如何都有独立EXPRESSION
的条目以明确它们不相关。)
您不能做的是提供一个 SQL 表达式作为 a 的一部分BOUNDFILLER
,或者在另一个字段的 SQL 表达式中引用一个EXPRESSION
,即:
REFNBR BOUNDFILLER,
EMPID EXPRESSION "(SELECT EMPID FROM lookuptable WHERE REFNBR = :REFNBR)",
EMPFIRSTNAME EXPRESSION "(SELECT FIRST_NAME FROM anothertable WHERE empid= :EMPID)",
...
因为那会抛出
SQL*Loader-291:列 EMPFIRSTNAME 的 SQL 字符串中的绑定变量 EMPID 无效。
两者的原因是一样的。从文档中:
对于读取的每个输入记录,绑定变量引用的字段的值将替换绑定变量。
它从文件中查看字段的值,而不是在任何转换形成 SQL 表达式之后。如果您仅REFNBR
用于该查找,那么您可能会考虑不直接引用它并执行以下操作:
EMPID "(SELECT EMPID FROM lookuptable WHERE REFNBR = :EMPID)",
EMPFIRSTNAME EXPRESSION "(SELECT FIRST_NAME FROM anothertable WHERE empid= :EMPID)",
...
但在EXPRESSION
评估中,它仍然使用文件中值的原始值 - 即实际上是 a REFBNR
- 而不是将插入为EMPID
. 所以找不到匹配项,或者与您想要的行不匹配,这可能更糟。
鉴于此,BOUNDFILLER
允许使用 SQL 表达式是没有意义的——该表达式的结果将永远不会被使用。
其他一些想法......显然重复子查询/连接是混乱的,所以我可以看到为什么可重用的修改值在这种情况下会很有用。但是由于您不能这样做,因此将原始REFNBR
(以及您需要从文件中的任何其他字段)加载到临时表中会更简单 - 正如@Littlefoot 建议的那样,无论是物理表还是外部表 - 然后查询并加入对其他表进行最终插入到目标表中。
它看起来——从一个非常人为的例子来看——就像你在复制数据,这可能是不明智的;实际上只具有REFNBR
或至少只EMPID
在目标表中而不是具有引用约束可能会更好,因此在查询时所做的任何更改都会anothertable
自动反映。这可能是归档和删除的更大过程的一部分,或者其他东西;但是,使用暂存/外部表并驱动整个过程仍然会更简单,而不是尝试让 SQL*Loader 完成其中的一些工作。