我可以在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)"
答案 0 :(得分:2)
关于如何从查找表填充BOUNDFILLER的任何想法?
不能。 (尽管文档中的措辞暗示您应该能够;我认为那是一个文档错误,应该说更多类似“无法将填充程序字段指定为另一个字段规范的SQL字符串的一部分,因为...”-然后BOUNDFILELR
的例外更有意义)。
如果EMPID
不是数据文件中的字段,则不需要填充。如果它在文件中但不在目标表中,则可以用普通的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
并具有独立的{{1 }}条目,以明确它们是不相关的。)
您不能做的是要么将SQL表达式作为EXPRESSION
的一部分提供,要么在另一个字段的SQL表达式中引用一个BOUNDFILLER
,即:
EXPRESSION
那样会抛出
SQL * Loader-291:SQL字符串中EMPFIRSTNAME列的绑定变量EMPID无效。
两者的原因是相同的。 From the documentation:
对于每个读取的输入记录,由绑定变量引用的字段的值将替换为绑定变量。
它从文件中查看字段的值,而不是在经过任何形式的SQL表达式转换之后。如果您仅使用REFNBR BOUNDFILLER,
EMPID EXPRESSION "(SELECT EMPID FROM lookuptable WHERE REFNBR = :REFNBR)",
EMPFIRSTNAME EXPRESSION "(SELECT FIRST_NAME FROM anothertable WHERE empid= :EMPID)",
...
进行查找,那么您可能会考虑不直接引用它并这样做:
REFNBR
,但是在EMPID "(SELECT EMPID FROM lookuptable WHERE REFNBR = :EMPID)",
EMPFIRSTNAME EXPRESSION "(SELECT FIRST_NAME FROM anothertable WHERE empid= :EMPID)",
...
评估中,它仍然使用文件中值的原始值-即实际上是EXPRESSION
-而不是将作为REFBNR
插入的最终值。因此找不到匹配项,也不会匹配您想要的行,这可能更糟。
鉴于此,EMPID
不允许使用SQL表达式-永远不会使用该表达式的结果。
还有其他一些想法...显然,重复子查询/联接很麻烦,因此我可以看到为什么在这种情况下可重用的修改值会很有用。但是由于您无法执行此操作,因此将原始BOUNDFILLER
(以及文件中需要的其他任何字段)加载到暂存表(如@Littlefoot建议的物理表或外部表)中会更简单,并且然后查询并联接到其他表,以最终插入目标表。
看起来-从可能是一个非常人为的示例-就像您正在复制数据,这可能并不明智;最好在目标表中只包含REFNBR
或至少只有REFNBR
而不使用引用约束,因此在查询EMPID
时所做的任何更改都会自动反映出来。这可能是归档和删除等较大过程的一部分。但是,使用临时表/外部表并驱使整个过程变得更简单,而不是尝试使SQL * Loader来完成某些工作,将会更加简单。
答案 1 :(得分:1)
另一种选择是切换到外部表(在后台,它使用SQL * Loader)。由于它表现为“普通”表,因此可以针对它编写(PL /)SQL。它包括联接,子查询等,因此您可以使用该查找表。