在Oracle Control File中,我可以从查找表中填充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)"
关于如何从查找表中填充BOUNDFILLER的任何想法?
你不能。 (尽管文档中的措辞暗示你应该能够;我认为这是一个doc bug,它应该说更像“填充字段不能被指定为另一个字段规范的SQL字符串的一部分,因为......” - 然后BOUNDFILELR
的例外更有意义)。
如果EMPID
不是数据文件中的字段,那么您不需要填充它。如果它在文件中但不在目标表中,则可以使用普通的FILLER
跳过它,除非您想稍后引用该文件值。如果它是目标表中的一列,那么您可以使用EXPRESSION
子句来进行查找,但之后您不能将其称为其他地方的绑定变量。
如果要在控制文件中的其他SQL的其他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表达式作为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。
两个原因都是一样的。 From the documentation:
对于读取的每个输入记录,绑定变量引用的字段的值将替换绑定变量。
它从文件中查看字段的值,而不是在从SQL表达式进行任何转换之后。如果你只是使用REFNBR
进行查找,那么你可能会考虑不直接参考和执行:
EMPID "(SELECT EMPID FROM lookuptable WHERE REFNBR = :EMPID)",
EMPFIRSTNAME EXPRESSION "(SELECT FIRST_NAME FROM anothertable WHERE empid= :EMPID)",
...
但在EXPRESSION
评估中,它仍然使用文件中值的原始值 - 即实际上是REFBNR
- 而不是将作为EMPID
插入的最终值。因此,找不到匹配项,或者与您预期的行不匹配,这可能更糟。
鉴于此,BOUNDFILLER
允许使用SQL表达式是没有意义的 - 该表达式的结果永远不会被使用。
其他一些想法......显然重复子查询/连接是混乱的,所以我可以看到为什么可重用的修改值在这种情况下会有用。但是既然你不能这样做,那么将原始的REFNBR
(以及你需要的任何其他字段)加载到一个临时表 - 或者像@Littlefoot建议的物理表或外部表 - 然后查询和连接到其他表以在目标表中进行最终插入。
它看起来 - 从可能是一个非常人为的例子 - 就像你复制数据,这可能是不明智的;实际上只需要在目标表中使用REFNBR
或至少只是EMPID
而不是参考约束,所以在anothertable
中进行的任何更改都会在查询时自动反映出来。这可能是存档和删除的更大过程的一部分,或者某些东西;但是,使用登台/外部表并驱动整个过程仍然更简单,而不是试图让SQL * Loader做一些工作。
另一种方法是切换到外部表(在场景后面,它使用SQL * Loader)。因为它表现为“普通”表,所以可以针对它编写(PL /)SQL。它包括连接,子查询等,因此您可以使用该查找表。