Oracle sqlldr:获取';ORA-19032:应为XML标记,未获取任何内容';对于空值

Oracle sqlldr:获取';ORA-19032:应为XML标记,未获取任何内容';对于空值,oracle,sql-loader,Oracle,Sql Loader,我正试图加载一个带有oracle sqlldr的表,但得到ORA-19032:预期的XML标记,在(允许!)空字段上没有内容 如果该表由insert填充,或者该列更新为null,则一切正常。但是通过sqlldr加载不起作用 加载器调用: sqlldr $DBCS control=$TABLE.ctl data=$TABLE.csv bad=$LOGDIR/$TABLE.bad log=$LOGDIR/$TABLE.log rows=10000 bindsize=20000000 readsize

我正试图加载一个带有oracle sqlldr的表,但得到
ORA-19032:预期的XML标记,在(允许!)空字段上没有内容

如果该表由insert填充,或者该列更新为null,则一切正常。但是通过
sqlldr
加载不起作用

加载器调用:

sqlldr $DBCS control=$TABLE.ctl data=$TABLE.csv bad=$LOGDIR/$TABLE.bad log=$LOGDIR/$TABLE.log rows=10000 bindsize=20000000 readsize=20000000 silent=header,feedback
CTL文件:

LOAD DATA
INFILE MY_TABLE.csv "STR '|\n'"
INTO TABLE MY_TABLE APPEND
FIELDS TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
  "NORMAL_COLUMN1" CHAR(40)
, "NORMAL_COLUMN2" CHAR(250)
, "NORMAL_COLUMN3" CHAR(250)
, "XML_COLUMN" CHAR(16000)
)
表定义:

CREATE TABLE MY_TABLE
(
  NORMAL_COLUMN1        NUMBER(14) not null,
  NORMAL_COLUMN2        VARCHAR2(250) not null,
  NORMAL_COLUMN3        VARCHAR2(250),
  XML_COLUMN            SYS.XMLTYPE    
);
csv行-不工作:

21001;"lulul";"lalal";|
csv行-工作:

21001;"lulul";;"<a>ala</a>"|
21001;“露露”;;“阿拉”|
注意:一般来说,我会为“普通列”创建“正确”的数据类型,但是ctl文件是由卸载脚本创建的……而且它可以工作;)

重要信息:它适用于xml列的非空值


我希望有一种方法可以修改ctl文件中的对应行,但我还没有找到解决方案。

问题似乎是,在加载程序执行过程中的某个点上,当
NULL
值作为参数传递给
XmlType(值)时,会出现类似于以下情况的情况
构造函数或
createXML(值)
函数:

select XmlType('') as xml_value from dual;
我尝试了一些方法来解决这个问题,但没有成功。当我有更多的时间时,我可以继续研究它,但我想至少把它作为一个解释。你可以通过做以下事情来解决这个问题:

LOAD DATA
INFILE MY_TABLE.csv "STR '|\n'"
INTO TABLE MY_TABLE APPEND
FIELDS TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
  "NORMAL_COLUMN1" CHAR(40)
, "NORMAL_COLUMN2" CHAR(250)
, "NORMAL_COLUMN3" CHAR(250)
, "Nvl(XML_COLUMN, '<empty />')" CHAR(16000)
)
加载数据
填充MY_TABLE.csv“STR'\n'”
在表MY_表中追加
以“;”结尾的字段
可选地由“”括起
尾随零线
(
“正常列1”字符(40)
,“正常列2”字符(250)
,“NORMAL_COLUMN3”字符(250)
,“Nvl(XML_列)”,“CHAR(16000)
)

这不是理想的解决方案,但它应该会让您继续前进。如果您最终选择了这条路线,请告诉我,否则我会看看是否可以找到更好的解决方案。

问题似乎是,在加载程序执行过程中的某个点上,当
NULL
值作为p传递时,会发生类似于以下情况的情况
XmlType(value)
构造函数或
createXML(value)
函数的参数:

select XmlType('') as xml_value from dual;
我尝试了几种方法来解决这个问题,但没有成功。我可以在有更多时间的时候继续研究它,但我想至少将此作为一种解释。你可以(黑客般地)通过以下方式来解决这个问题:

LOAD DATA
INFILE MY_TABLE.csv "STR '|\n'"
INTO TABLE MY_TABLE APPEND
FIELDS TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
  "NORMAL_COLUMN1" CHAR(40)
, "NORMAL_COLUMN2" CHAR(250)
, "NORMAL_COLUMN3" CHAR(250)
, "Nvl(XML_COLUMN, '<empty />')" CHAR(16000)
)
加载数据
填充MY_TABLE.csv“STR'\n'”
在表MY_表中追加
以“;”结尾的字段
可选地由“”括起
尾随零线
(
“正常列1”字符(40)
,“正常列2”字符(250)
,“NORMAL_COLUMN3”字符(250)
,“Nvl(XML_列)”,“CHAR(16000)
)

这不是理想的解决方案,但它应该会让你前进。如果你最终只是走这条路,请告诉我,否则我会看看是否能找到更好的方法。

使用nval函数和XMLTYPE来提供伪xml,以防出现空值


EXTRACTVALUE(XMLTYPE(nvl(XML_列,'1')),“/XPATh/”)

将nval函数与XMLTYPE一起使用,以在出现空值时提供伪XML


EXTRACTVALUE(XMLTYPE(nvl(XML_COLUMN,'1')),“/XPATh/”)

谢谢,我甚至考虑过这个解决方案,但是当我得到一个约束时,
NORMAL_COLUMN3 XOR XML_COLUMN
NULL
,所以在解决方案之后我需要一个解决方案,如果我这样做的话:(@evilive您可以在检查传入值的表的
行触发器之前放置一个
,如果它等于“”,则将其设置为null。这应该可以解决问题。@gimley:好的,再次感谢您,但这太脏了;)我选择XML数据类型为“关闭”另一个表,因为如果它可以工作会更好(手动查询中的XPATH,不可能有无效的XML结构等)。但是由于应用程序也可以使用varchar2,我现在切换到该表,我们所有的“标准过程”都可以像以前一样工作。无论如何,我会接受你的答案,因为ORA-19032将不复存在;)谢谢,我甚至想过这个解决方案,但有一刻我得到了一个约束,即
NORMAL\u COLUMN3 XOR XML\u COLUMN
NULL
,因此在解决方案之后我需要一个解决方案,如果我这样做的话:(@evilive您可以在检查传入值的表的
行触发器之前放置一个
,如果它等于“”,则将其设置为null。这应该可以解决问题。@gimley:好的,再次感谢您,但这太脏了;)我选择XML数据类型为“关闭”另一个表,因为如果它能工作会更好(手动查询中的XPATH,不可能有无效的XML结构等)。但是由于应用程序也可以使用varchar2,我现在只切换到该表,我们所有的“标准流程”都可以一如既往地工作。无论如何,我会接受你的答案,因为ORA-19032将不复存在;)