我希望使用XMLEXISTS函数对包含text
内容的XPATH列执行查询。例如:
select * from om_table tb
WHERE xmlexists('//town[text() = ''Toronto'']' PASSING BY REF tb.config_xml);
哪个config_xml是text
列。但它会出错:
错误:函数pg_catalog.xmlexists(未知,文本)不存在
我也在character varying
列上测试过它,但它也会出错:
错误:函数pg_catalog.xmlexists(未知,字符变化)不存在
但是,如果我使用硬编码的XML值,它将成功执行:
select * from om_table tb
WHERE
xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Toronto</town><town>Ottawa</town></towns>');
我该怎么办?(我正在使用PostgreSQL 9.6
)
发布于 2017-11-20 12:38:01
你应该使用例如将你的文本转换成XML类型。XMLPARSE(DOCUMENT tb.config_xml)
,如本例所示:http://sqlfiddle.com/#!17/9f0fb/7/0
还可以考虑将config_xml
作为XML列而不是文本列。
发布于 2017-11-20 13:40:08
您的config_xml
是text
类型,但是测试时的文字是xml
类型。
这是因为我花了一段时间才习惯了: Postgres中的单引号不被认为是文本/varchar值,实际上是“未知类型的文字”。另一方面,列的类型总是固定的。
规划者将在可能的情况下推断类型;在xmlexists('//foo' PASSING BY REF '<foo />')
上下文中,唯一匹配的函数采用xml
类型的参数,因此'<foo />'
被解释为xml
文字。这与将值从text
转换为xml
不同,正如编写文字123
与将字符串'123'
转换为int不一样。
要直接声明文字的类型,可以使用语法type 'value'
,因此在本例中,正确的显式形式是xmlexists(text '//foo' PASSING BY REF xml '<foo />')
。如果您编写的是xmlexists(text '//foo' PASSING BY REF text '<foo />')
,那么在使用text
列时会得到相同的错误。
要解决这个问题,您应该将列转换为xml
类型,而不是text
类型,或者在调用函数如手册所述时转换值。
若要从字符数据中生成xml类型的值,请使用函数xmlparse:
XMLPARSE ( { DOCUMENT | CONTENT } value)
示例:XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>')
XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')
https://stackoverflow.com/questions/47391886
复制相似问题