我正在使用sqlldr将csv文件中的数据加载到表中。 csv文件的每一行都有一列不存在。填充此列所需的数据存在于该行的其他列之一中。我需要拆分(拆分(。))该列的数据并填充到该列中。
如: -
column1:- abc.xyz.n
所以未知列(column2)应该是
column2:- xyz
此外,行中还有另一列,但它不是我想要输入到表中的列。它还需要从column1填充。但是那里有大约50个if-else案例。解码比这更好吗?
column1:- abc.xyz.n
然后,
column2:- hi if(column1 has 'abc')
if(column1 has 'abd' then 'hello')
像这样,大约有50个if-else案例。
感谢您的帮助。
答案 0 :(得分:2)
对于问题的第一部分,将控制文件中的column1数据定义为BOUNDFILLER,其名称与表列名称不匹配,告诉sqlldr记住它但不使用它。如果需要将其加载到列中,请使用列名称和记住的名称。对于column2,在表达式中使用记住的BOUNDFILLER名称,它返回所需的部分(在本例中为第二个字段,允许NULL):
x boundfiller,
column1 EXPRESSION ":x",
column2 EXPRESSION "REGEXP_SUBSTR(:x, '(.*?)(\\.|$)', 1, 2, NULL, 1)"
请注意,需要使用双反斜杠,否则当它从sqlldr传递到正则表达式引擎时会被删除,并且正则表达式模式会被错误地更改。我想是一个怪癖。
无论如何,在此列1结束后," abc.xyz.n"和column2得到" xyz"。
对于问题的第二部分,您可以使用已经显示的表达式,但调用您创建的自定义函数,其中您传递提取的值,它将从查找表返回搜索的值。您当然不想对50个查找值进行硬编码。您也可以在表级触发器中执行相同的操作。注意我只为一个示例显示了一个select语句,但是这应该封装在一个可重用性和可维护性的函数中:
只是为了表明你可以做到:
col2 EXPRESSION "(select 'hello' from dual where REGEXP_SUBSTR(:x, '(.*?)(\\.|$)', 1, 2, NULL, 1) = 'xyz')"
正确的方式:
col2 EXPRESSION "(myschema.mylookupfunc(REGEXP_SUBSTR(:x, '(.*?)(\\.|$)', 1, 2, NULL, 1)))"
mylookupfunc返回查找结果' xyz'在查找表中,即'你好'按照你的例子。