0

在 Oracle 控制文件中,我可以从查找表中填充 BOUNDFILLER 吗?

例如:

EMPID BOUNDFILER "SELECT EMPID from employees where refno=refno"

我试过了,但我得到一个错误消息,我想是因为这是不可能的?

错误消息是:期望有效的列规范,“,”或“)”,找到...。

关于如何从查找表中填充 BOUNDFILLER 的任何想法?

编辑:显然我不太清楚问题是什么。

我需要从查找表中填充 BOUDFILLER。当值来自源文件时,一切正常。

谢谢你。

这里还有几行代码可以可视化我正在尝试做的事情:

EMPID      BOUNDFILLER "(SELECT EMPID FROM table WHERE REFNO = :REFNBR)" (Trying to get empid from another table to use below)
EMPFIRSTNAME "(SELECT FIRST_NAME FROM table WHERE TRANS = :TRANS AND FILENAME =:FILENAME)"
EMPLASTNAME  "(SELECT LAST_NAME FROM table WHERE TRANS = :TRANS AND FILENAME =:FILENAME)"
EMPEMAIL    "(SELECT EMPEMAIL FROM table WHERE EMPID = :EMPID)"
EMPSUPERVISORNAME   "(SELECT EMPSUPERVISORNAME FROM table WHERE EMPID = :EMPID)"
EMPHOMECITY      "(SELECT EMPHOMEOFFICECITY FROM table WHERE EMPID = :EMPID)"
4

2 回答 2

2

关于如何从查找表中填充 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 完成其中的一些工作。

于 2019-03-02T19:43:04.157 回答
1

另一种方法是切换到外部表(在后台,它使用 SQL*Loader)。由于它的行为类似于“普通”表,因此您可以针对它编写 (PL/)SQL。它包括连接、子查询等,因此您可以使用该查找表

于 2019-03-02T19:04:58.873 回答