Oracle 如何创建SQLLDR控制文件来处理包含断开行的文本文件?

Oracle 如何创建SQLLDR控制文件来处理包含断开行的文本文件?,oracle,sql-loader,Oracle,Sql Loader,因此,例如,包含要加载的数据的文本文件可能如下所示: $ cat employee.txt 100,Thomas,Sales,5000 200,Jason,Technology,5500 300,Mayla, Technology,7000 400,Nisha,Marke ting,9500 500,Randy,Technology, 6000 501,Ritu,Accounting,5400 您可以看到,某些行在错误的点包含换行符。其中一个甚至在实际的字符串中间断裂。因此,我在尝试运行SQL

因此,例如,包含要加载的数据的文本文件可能如下所示:

$ cat employee.txt
100,Thomas,Sales,5000
200,Jason,Technology,5500
300,Mayla,
Technology,7000
400,Nisha,Marke
ting,9500
500,Randy,Technology,
6000
501,Ritu,Accounting,5400
您可以看到,某些行在错误的点包含换行符。其中一个甚至在实际的字符串中间断裂。因此,我在尝试运行SQL加载程序时收到一个错误


因此,我想知道是否有任何参数可以添加到加载或控制文件中,以处理如此混乱的数据文件。我在想是否有一种方法可以计算文本文件中的第n个逗号,以确定下一行何时开始。

一种方法是定义不同的记录分隔符,然后将分隔符附加到输入文件的每个“行”的末尾。比如:

sqlldr.ctl:

LOAD DATA
CHARACTERSET UTF8
INFILE employee.txt "str ' 0X1E\n'"
TRUNCATE INTO TABLE <table name>
TRAILING NULLCOLS
(
    ...
)

请注意,在本例中,“0X1E”是一个文本字符串,而不是0X1E(ASCII记录分隔符)的十六进制值,我永远无法正确使用该值…

您需要在控制文件中使用
CONTINUEIF
子句。这将强制
sqlldr
查看最后一个字符,如果它与字符串匹配(在您的示例中为逗号),它将在继续之前将下一行连接到当前行

根据新信息进行编辑。让我们从源头开始。在发送之前,能否要求源代码修复此问题?如果是供应商,依靠他们不要发送垃圾数据!如果来自源程序,则应从列表中选择部门,而不是徒手输入,用户可以按enter键或谁知道还有什么。这就是说,如果你必须处理你所得到的(我们都在那里),你必须在加载之前以某种方式预处理这些数据。这是一个很滑的斜率,因为你必须想出一些规则来检测断言是在词的中间。
可能是一个awk或sed脚本,它查看每一行,如果最后一个逗号后的最后一组字符不符合列应包含的规则,则假定该行已断开并连接下一行?您必须进行一些分析,以确定逻辑是否适合您。

这真是太棒了!但是我意识到在文本文件中,一条记录打断了实际的字符串,因此这行以字符串文本的一半结束,下一行是另一半。有解决这个问题的方法吗?编辑你的原始帖子,并在你的测试数据中添加一个例子。包括一条注释以指示更改。完成。参见示例记录:400,Nisha,Marketing,9500参见新注释。编辑:示例中的一条记录已更改,以显示文本文件行中断位置的进一步示例。参见记录示例:400,Nisha,Marke ting,9500这只是一个小示例。通常我会收到包含数十万行的记录。我不认为在每一行后面都附加ASCII分隔符太实际。还有别的解决办法吗?注意:我在文本文件示例中添加了一个小的编辑。@Phillip-这是我最终使用的解决方案,但随后我还创建了加载程序文件。我也不是sqlldr专家。如果您是从其他地方获取这些文件,您如何/将如何确定每条记录的结尾位置?通常是根据存在的列数。例如,如果有15列,那么行中的最后一个字段位于第15个终止符之后。这就是为什么我想知道是否有一种方法可以确定数据文件中何时出现第n个逗号或任何终止符,以及是否可以使用某种类型的参数对其进行调整。
100,Thomas,Sales,5000 0X1E
200,Jason,Technology,5500 0X1E
300,Mayla,
Technology,7000 0X1E
400,Nisha,Marketing,9500 0X1E
500,Randy,Technology,
6000 0X1E
501,Ritu,Accounting,5400 0X1E
load data
infile 'testdata.dat'
continueif last = ','
into table testtable
truncate 
fields terminated by ',' 
(
empid,
ename,
dept,
salary 
)