在尝试修复解析包含日期的XML文本时引发的转换错误时,出现了该问题。由于输入XML相当大,因此决定创建一个查询,显示错误的XML元素片段(只是为了检查是否可以用其他方式处理它们)。在WHERE子句中使用VALIDATE_CONVERSION函数似乎是一个很好的选择。但是,一旦涉及到该函数,查询就失败了。由于原始查询看起来太庞大,我试图剥离它以进行澄清。结果低于
--------- This query works fine
with q_test as (
select 1 as id, '2023-08-26' as dt from dual
union all select 2, 'Invalid date' from dual
)
select q.*, validate_conversion(q.dt as date, 'yyyy-mm-dd')
from q_test q;
--------- This one fails
with q_test1 as (
select XMLTYPE('<?xml version=''1.0'' encoding=''UTF-8''?>
<TEST>
<RECORD>
<ID>1</ID>
<DT>2023-08-26</DT>
</RECORD>
<RECORD>
<ID>2</ID>
<DT>Invalid date</DT>
</RECORD>
</TEST>') xml
from dual
),
q_test2 as (
select cast(t1.id as number) as id, t1.dt
from q_test1 q1,
XMLTABLE('//TEST/RECORD' passing q1.xml
columns
ID path 'ID'
, DT path 'DT'
) t1
)
select q2.*, validate_conversion(q2.dt as date, 'yyyy-mm-dd') from q_test2 q2;
这里可疑的功能被放置在SELECT子句中,但效果是一样的。虽然这些查询被期望产生相同的结果,但它们并没有。第一个返回两行,如下所示
第二个查询发出错误“ORA-43909:输入数据类型””无效。错误的描述指出,对于DATE输出类型,输入数据类型可以是CHAR、NCHAR、VARCHAR 2或NVARCHAR 2,在这种情况下似乎是真的,但错误仍然发生。如果从两个查询中删除VALIDATE_CONVERSION函数调用,则它们返回的结果相同。数据库:Oracle数据库12 c企业版12.2.0.1.0 - 64位生产
假设XMLTABLE操作符可能会产生一个不允许的数据类型,我尝试将dt列的值转换为varchar 2(20)类型,但结果是一样的。既然我认为XMLTABLE和VALIDATE_CONVERSION是矛盾的,那么可能有一种解决方法,将清除函数的查询结果存储在某个临时表中,然后将该函数应用于其内容,但这种方法对于真实的查询来说是不方便的,并且可能导致性能问题
1条答案
按热度按时间sg2wtvxw1#
您可以将代码简化为:
它在Oracle 21和Oracle 23中工作,但在Oracle 18中失败(我假设是Oracle 12,但我没有该版本的示例来测试),错误为
ORA-43909: invalid input data type
。如果注解掉
VALIDATE_CONVERSION
,则查询可以工作(在DT
列上使用DUMP
表明数据类型为1
,即VARCHAR2
,因此XMLTABLE
输出的是正确的类型。要么:
1.将您的数据库升级到可以运行查询的版本。
1.联系Oracle支持(根据您的支持合同,假设您有这样一个旧版本的数据库),并询问他们是否有此错误的补丁。