如果xquery不存在,请使用xquery创建路径

时间:2011-06-28 06:33:49

标签: db2 xquery

我有一个xml结构,如下所示:

<data>
  <a>
    <element name="aName">123</element>
    <element name="xyz">foobar</element>
  </a>
  <b>
    <element name="aName">foo</element>
    <element name="otherName">bar</element>
  </b>
</data>

哪个保存在DB2数据库的XML列中。在/ a / element / @ name中是唯一的,/ b / element / @ name是唯一的等等。

现在我要在其中插入一个新的元素标记。如果已经存在具有相同name属性的元素,我想替换该元素(元素标记的顺序无关紧要)。我是这样做的:

update mytable set myXmlColumn=xmlquery('copy $new := $old modify
  (
    do delete $new/data/a/element[@name=$newName],
    do insert $insert as last into $new/data/a
  ) return $new'
  passing
    'aName' as "newName",
    xmlparse(document '<element name="aName">aaa</element>') as "insert"),
    myXmlColumn as "old"
) where id=123

这会直接插入新元素,删除另一个具有相同名称的元素(如果存在)。但是知道我希望这个工作即使标签还不存在(在这种情况下应该创建一个空标签并且应该添加新元素),如果myXmlColumn以前是空的,它仍然可以工作。

对于后一个要求,我找到了一个解决方案,虽然它让我觉得相当不优雅:在传递部分我可以编写coalesce(myXmlColumn,xmlparse(document '<data><a /></data>')),如果myXmlColumn为null,这将使语句有效。但是,如果它不是空的,但只是缺少了呢?

2 个答案:

答案 0 :(得分:1)

我找到了一个有效的解决方案,尽管它仍然感觉很尴尬。我想知道是否有更优雅的解决方案...

update mytable set myXmlColumn=xmlquery('copy $xml := (if (not($xml/data/a)) then transform copy $xml := $xml modify (do insert <a/> as last into $xml/data) return $xml else $xml) modify
  (
    do delete $xml/data/a/element[@name=$newName],
    do insert $insert as last into $xml/data/a
  ) return $xml'
  passing
    'aName' as "newName",
    xmlparse(document '<element name="aName">aaa</element>') as "insert"),
    COALESCE(myXmlColumn, xmlparse(document '<data/>')) as "xml"
) where id=123

答案 1 :(得分:0)

您可以在XQuery表达式中添加if-then逻辑,根据存在的节点添加不同数量的XML。这种方法可以让您获得最大的灵活性,因为它可以编程来处理几乎任何可能的情况,例如where / data存在,而不是/ data / a。当根文档元素不是<data>时,您甚至可以决定要做什么。

至于COALESCE(),我喜欢它并认为它是你所描述的条件的一个有价值的解决方法。