数据未从 sql 加载器填充
我有一个控制文件 loader.ctl,位于 C:\oracle\product\10.2.0\oradata\orcl 中。
loader.ctl 文件的内容为
load data
infile 'd:\mydata\test.csv'
into table emp1
fields terminated by "," optionally enclosed by '"'
( empno, ename,job,mgr,hiredate,sal,comm,deptno )
emp1
表已存在于数据库中,并且 test.csv 中有 9 条记录
我从 sqlldr 执行了 loader.ctl:
现在,当我检查数据库时,我发现 emp1
中没有记录...这是为什么所以?提交后为什么数据没有填充到表中?
I have a control file, loader.ctl, in C:\oracle\product\10.2.0\oradata\orcl
.
Content of loader.ctl file is
load data
infile 'd:\mydata\test.csv'
into table emp1
fields terminated by "," optionally enclosed by '"'
( empno, ename,job,mgr,hiredate,sal,comm,deptno )
emp1
table is already present in the database and there are 9 records in test.csv
I executed loader.ctl from sqlldr:
Now, when I check my database I find no records in emp1
... why is this so? After the commit why is the data not being populated in the table?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您还没有指定日志文件,这意味着它可能与您的 ctl 文件位于同一位置,但它也可能位于您调用 SQL*Loader 的目录或数据所在的目录中 - 顺便说一句,这是一个很好的选择想法是从存储 ctl 文件的同一位置调用 SQL*Loader 以避免混淆。去寻找它和相关的坏文件。
我总是会在命令行或 ctl 文件中明确说明日志和错误的位置 - 并在适当的情况下丢弃文件。我更喜欢命令行,这样您就可以将它们全部放在不同的文件夹中,这样它们就不会相互覆盖。因此,您不必每次加载内容时都更改 ctl 文件,您还可以将数据文件(以及几乎所有其他内容)放在命令行中。像这样的事情:
您的问题有两个可能的原因。
正如 @JustinCave 所建议的,您只是从错误的表中进行选择。我们暂时将其放在一边。
您已经注意到您已到达提交点,因此表中应该有数据。事实并非如此。您已达到提交点,但是根据您发布的 ctl 文件,您尚未指定允许的错误数。这意味着 SQL*Loader 使用默认值 - 50。有可能到达一个提交点,在该点之前加载的所有内容都是错误的;即您没有提交任何内容。
第 2 点是最有可能导致您的问题的原因。查看日志文件,它应该以不一定很有帮助的方式告诉您为什么会出现错误。坏文件包含所有尚未加载的数据,您可以根据日志进行检查。
发生第二个问题的原因有很多,因此这里列出了 SQL*Loader 可能出现的问题:
TRAILING NULLCOLS
。hiredate
,它将在 ctl 文件中变为hiredate "to_date(:hiredate,'yyyy/mm/dd')"
,其中 < code>yyyy/mm/dd 更改为您需要的任何日期格式。有关详细列表,请参阅此处。当然,您始终可以将此列更改为字符并稍后处理转换。to_number
函数:sal "to_number(:sal,'999.99')"
。与日期一样,您始终可以将此列更改为字符并稍后处理转换。deptno
更改为以空格终止的deptno
。sal integer external
,这会明确告诉 SQL*Loader 它是一个数字。.txt
给.exe
任何人?字符集
选项。在我的脑海中,这就是像你这样简单的负载可能出现的大部分问题。
现在是建议。 指定。就这么简单。如果您不利用 SQL*Loader 极其强大的特性及其提供的无数选项,您将遇到这样的问题。不仅如此,当供应商在没有告诉您的情况下更改某些内容时,您不太可能注意到这些更改。
我还强烈建议始终在加载后检查日志文件。通常,这是检查加载是否成功的唯一方法之一。 SQL*Loader 在几乎每个错误栏
ORA-01653
上都会默默失败 - 空间不足,并将有关这些错误的所有信息放入日志文件中。除非你检查,否则你不会知道它们。典型的 ctl 文件通常看起来像这样:
所有这些东西,除了列名和表名都是可选的。
我添加的内容是:
skip
- 顶部要跳过的行数。errors
- 停止前的最大错误数。rows
- 提交之前加载的行数。direct
- 使用直接路径加载。TRUNCATE
- 在加载之前截断表TRAILING NULLCOLS
- 文件末尾有空列。"to_date(..."
- 指定加载此列时要调用的 Oracle 函数integer external
- 强制此列为数字数据类型。以空格终止< /code> - 删除行或列末尾的空格
这里有
一些链接非常适合进一步阅读和对所有可用选项的更多解释:
http://docs.oracle.com/cd/B19306_01/server.102 /b14215/ldr_params.htm
http://www.orafaq.com/wiki/SQL*Loader_FAQ
http://www.oracleutilities.com/OSUtil/sqlldr.html
Firstly you haven't specified a log file, which means it's probably in the same place as your ctl file but it could also be in the directory you called SQL*Loader from or the directory the data is in - as an aside it's a good idea to call SQL*Loader from the same place you store the ctl file to avoid confusion. Go looking for it and the associated bad file.
I would always explicitly state the location of the log and bad - and discard file if appropriate - either in the command line or in the ctl file. I prefer the command line so you can put them all in different folders so they don't overwrite each other. So you don't have to change the ctl file every time you load something you can also put the data file (and almost everything else) in the command line. Something like this:
There are two probable reasons for your problem.
As @JustinCave suggested you're simply selecting from the wrong table. We'll put this aside for now.
You've noted that you've reached a commit point so there should be data in the table. This is not at all the case. You have reached a commit point, but, according to your posted ctl file, you haven't specified the number of errors allowed. This means SQL*Loader is using the default - 50. It's possible to reach a commit point, where everything loaded before it is errors; i.e. you're committing nothing.
Point 2 is the most likely cause of your problem. Look in the log file and it should tell you, in a not necessarily very helpful way, why you've got errors. The bad file contains all the data that hasn't been loaded, which you can check against the log.
There are quite a few reasons for the second one to occur so here's a list of things that can go wrong with SQL*Loader:
TRAILING NULLCOLS
.hiredate
, which would becomehiredate "to_date(:hiredate,'yyyy/mm/dd')"
in the ctl file, whereyyyy/mm/dd
is changed to whatever date format you need. See here for a good list. Of course you could always change this column to a char and deal with the transformation later.to_number
function:sal "to_number(:sal,'999.99')"
. As with dates you could always change this column to a char and deal with the transformation later.deptno
todeptno terminated by whitespace
.sal integer external
, which explicitly tells SQL*Loader it's a number..txt
to.exe
anyone? )characterset
option.Off the top of my head that's most of what could go wrong with a load as simple as yours.
Now the advice. Specify. It's as simple as that. If you don't take advantage of the extremely powerful nature of SQL*Loader and the myriad of options it provides you will come across problems like this. Not only that when a supplier changes something without telling you you're less likely to notice the change.
I would also highly recommend ALWAYS checking the log file after a load. Normally this is one of the only ways of checking that your load was successful. SQL*Loader fails silently on almost every error bar
ORA-01653
- not enough space and puts all information about these errors in the log file. You will not know about them unless you check.A typical ctl file would normally look something like this:
All these things, bar the column names and the table name are optional.
The ones I've added are:
skip
- Number of rows at the top to skip.errors
- The maximum number of errors before stopping.rows
- The number of rows to load before committing.direct
- Use direct path load.TRUNCATE
- Truncate the table prior to loadingTRAILING NULLCOLS
- There are null columns at the end of your file."to_date(..."
- Specify an Oracle function to call when loading this columninteger external
- Force this column into a number datatype.terminated by whitespace
- Remove whitespace at the end of the line or column.There's loads more.
Here are a few links that are great for further reading and more explanation of all the possible options available to you:
http://docs.oracle.com/cd/B19306_01/server.102/b14215/ldr_params.htm
http://www.orafaq.com/wiki/SQL*Loader_FAQ
http://www.oracleutilities.com/OSUtil/sqlldr.html