【问题标题】:SQL Query on DB2. contains function on XML columnDB2 上的 SQL 查询。包含 XML 列上的函数
【发布时间】:2016-05-25 18:12:39
【问题描述】:

我的test 表有两列,一列是message_xml,类型为XML,另一列是company_names,类型为VARCHAR。我想在每个 XML 行中搜索一个单词,如果 XML 有,则导出该 XML。

这里有 2 个存储在 DB2 中的 xml 示例:

<breakfast_menu>
  <food>
    <name>Belgian Waffles</name>
    <price>$5.95</price>
    <description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>
    <calories>650</calories>
  </food>
  <food>
    <name>Homestyle Breakfast</name>
    <price>$6.95</price>
    <description>Two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
    <calories>950</calories>
  </food>
</breakfast_menu>

<breakfast_menu>
  <food>
    <name>Strawberry Belgian Waffles</name>
    <price>$7.95</price>
    <description>Light Belgian waffles </description>
    <calories>900</calories>
  </food>
  <food>
    <name>French Toast</name>
    <price>$4.50</price>
    <description>Thick slices of bread</description>
    <calories>600</calories>
  </food>
</breakfast_menu>

在这些 XML 文档中,我想找到单词“bacon”(它可以在 XML 中的任何位置),然后将该 XML 导出到文本文件中。

我尝试通过首先将 XML 转换为字符串来使用 CONTAINS,但我收到关于 VARCHAR 的错误。

xmlcast(test.message_xml as varchar(255)) as export_XML 是我编写的将 XML 转换为字符串的代码

[错误代码:-16061,SQL 状态:10608] 值“429541527005540133404021548131000109999-12-312...”不能构造为或强制转换(使用隐式或显式强制转换)数据类型“VARCHAR_255”。错误 QName=err:FORG0001.. SQLCODE=-16061, SQLSTATE=10608, DRIVER=4.15.82

接下来我直接尝试使用CONTAINS,但我收到关于未找到文本索引的错误。所以,我试图创建一个索引,但我也得到了一个错误,错误显示为

“在 "L) 之后发现了一个意外的标记 "idx1" 作为 (create index"。预期的标记可能包括:"JOIN""

代码: 在 test(message_xml) 上创建索引 idx1 使用 xmlpattern '/XML' 生成密钥 作为 varchar(9999)

我的代码是:

@export on;
@export set filename="D:\temp\searchResults.txt";
@set maxrows 10;
with Tempresult(export_xml)
as
(
create index idx1 on test(message_xml)
generate key using xmlpattern '/XML'
as varchar(9999)
select 
    test.message_xml as export_XML
from test where source_id = 14
and trans_timestamp between '2015-10-01' and '2016-04-30'
)
select
    export_XML
    from Tempresult
    //where LOCATE('bacon',export_XML) > 0;
    where CONTAINS(export_XML, ' "bacon" ') = 1;
@export off;

使用上面的代码没有创建索引,我得到这个错误:

[错误代码:-443,SQL 状态:38799] 例程“*RCH_8K64”(特定名称“”)返回了错误 SQLSTATE,诊断文本为“CTE0199 没有对应于列“MESSAGE_XML”的文本索引”.. SQLCODE= -443, SQLSTATE=38799, DRIVER=4.15.82

我什至尝试使用LOCATECONVERTCAST,但没有用。有人可以帮我解决这个问题吗?

我认为解决方案可能是将 XML 转换为字符串并应用 CONTAINSLOCATE 或为 xml 列创建索引。如果我错了,请纠正我。

【问题讨论】:

  • 我用来将 xml 转换为字符串的代码是:“xmlcast(test.message_xml as varchar(9999)) as export_XML”。我在varchar中使用了大量是因为我想导出我正在搜索的单词的整个xml。
  • 与其展示你解决问题的尝试,不如更好地描述问题本身。显示表定义、一些示例数据和所需的结果。而不是说“关于 VARCHAR 的错误”发布实际的错误代码和完整的消息。我怀疑可能有更简单的解决方案。顺便说一下,XML 索引不同于文本索引,这是 CONTAINS 函数工作所必需的。
  • 我列出了我的尝试,因为我担心我可能会得到我尝试过的解决方案。如果我列出了错误,那么有人可以建议我对此进行更正。我同意我没有提供您要求的详细信息,对此我深表歉意。我会提供的。你能帮我创建一个文本索引吗?
  • 如果您决定使用文本搜索功能,read the documentation 关于启用它并创建文本索引;您不能将文本搜索命令作为查询的一部分嵌入。
  • 感谢 mustaccio 编辑我的问题 :)。当然,我会浏览文档。再次感谢您。

标签: xml db2 contains xmlindex


【解决方案1】:

您应该利用 DB2 的PureXML 特性。例如,以下WHERE 子句将在元素 namedescription 中的任意位置搜索 bacon

WHERE XMLEXISTS('/breakfast_menu/food[contains(name,"bacon") or contains(description,"bacon")] ' PASSING message_xml)

【讨论】:

  • 太棒了。感谢您的回复 Stavr00。如果“培根”是标签中的名称属性怎么办。像这样:&lt;quantity name="bacon"&gt; 1 &lt;/quantity&gt;。如何编辑 WHERE 子句?有没有办法可以作为文本搜索?有时我需要处理非常非常大的 xml。
  • ... 那么这变成了XPATH 问题;)
  • 哦,明白了。我会尝试你的建议并回复你。谢谢你。同时,您能建议一种使用文本搜索的方法吗?当我尝试这样做时,列上没有文本索引。
  • XMLSERIALIZE(message_xml AS CLOB) 会将 XML 转换为可搜索的类型。但我还是推荐使用 XPATH 来搜索数据。
  • 我试过这个 Stavr00:WHERE XMLEXISTS('$clam//breakfast_menu/*[contains(name,"bacon")]' PASSING message_xml as "clam") 虽然我的 xml 有“bacon”属性,但它返回了 0 个结果。我错过了什么吗?谢谢 Stavr00。
【解决方案2】:

由于 XMLSERIALIZE(我认为),我以牺牲一些运行时间为代价找到了解决方案。

select message_xml AS export_xml from test where LOCATE('bacon',XMLSERIALIZE(xmlquery('$clam//breakfast_menu ' passing test.message_xml as "clam") as CLOB)) > 0

现在这对我有用。有时我会收到一条错误消息:

[错误代码:-433,SQL 状态:22001] 值“et">0.00”太长.. SQLCODE=-433, SQLSTATE=22001, DRIVER=4.15.82

我不知道这个错误是什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 2021-08-14
    • 1970-01-01
    • 2014-12-11
    • 2020-10-05
    • 1970-01-01
    相关资源
    最近更新 更多