今天有同事写信问我:"刚才在用SQLLDR导入的过程中发现一个小问题:就是SQLLDR rejected了两条数据,这两条数据的末尾都包含ascii码值为165的字符。附件是导入时用到的control文件以及SQLLDR的日志文件,导入数据表的对应列为varchar2(500)类型的。烦请您帮忙看看,为什么会出现这种被rejected的情况。谢谢"
我看了看日志,oracle这里显示reject的原因为Multibyte character error。
找他要了源文件,用sqlldr重现一下错误,果然有两条数据插入不进去。
我看了一下sqlldr产生的bad file,发现这两行数据末尾都显示为?,这里我高度怀疑就是这个问号的问题。
用ultraEdit看了一下这个?的16进制码,ultraEdit显示这个?的16进制码是A5,A5其实就是ascii 165,如下所示:
SQL> select to_number('A5','XX') from dual;
TO_NUMBER('A5','XX')
--------------------
165
然后我查了一下ASCII表,发现ASCII 165是¥。
你把上述字符随便保存到一个文本文档里,windows会提示你这个文本文档里包含unicode字符。
呵呵,原来是这样,那知道原因了,就很好处理了,设置一下NLS_LANG就OK了,如下所示:
如果保持NLS_LANG为默认值,则那两条错误数据导不进去:
E:\>sqlldr ipra/acca@ipradev control=ATPCO.ctl data=LKTCN081121.bad
SQL*Loader: Release
Copyright (c) 1982, 2005, Oracle. All rights reserved.
这里sqlldr实际上是一条数据都没有导入进去。
设一下NLS_LANG,马上就看出区别来了:
E:\>set NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1
E:\>sqlldr ipra/acca@ipradev control=ATPCO.ctl data=LKTCN081121.bad
SQL*Loader: Release
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Commit point reached - logical record count 2
这里sqlldr已经把那两条错误的数据导入进去了,如下所示:
SQL> select substr(oatint,303) from owbatptemp;
SUBSTR(OATINT,303)
--------------------------------------------------------------------------------
DIP *2BJ104¥
DIP *2BJ104¥
Leave a comment