【问题标题】:Using MERGE with XMLQUERY and transform将 MERGE 与 XMLQUERY 和转换一起使用
【发布时间】:2013-04-25 14:42:21
【问题描述】:

使用 DB2 LUW 10.1。我无法让 MERGE 处理具有使用 XQUERY 转换合并的 XML 列的两个表。

我有一张如下所示的表格:

create table foo (
  id int not null primary key,
  data xml not null
)

为了将数据加载到这个表中,我将它(使用 LOAD)加载到一个临时表中,如下所示:

create table foo_incoming (
  id int not null,
  data xml not null
)

使用 XQUERY 转换合并 XML 列中的数据。它背后有一些逻辑,所以它并不简单,但也不是太复杂。我已经使用手动更新测试了转换,所以我知道它有效。

然后我尝试像这样合并两个表:

merge into foo f
  using (select * from foo_incoming) i
  on (f.id = i.id)
  when matched then
    update set data = xmlquery('
        transform
          copy $out := $old
          modify ( ... )
          return $out'
        passing f.data as "old", i.data as "new")
  when not matched then
    insert (id, data) values (i.id, i.data)

当 foo 中有数据时,这非常有效。 XML 列完全按照我想要的方式合并。但如果 foo 为空,我会收到此错误:

SQL16084N  An assigned value in the copy clause of a transform expression is
not a sequence with exactly one item that is a node. Error QName=err:XUTY0013.
SQLSTATE=10705

似乎 DB2 正在尝试评估 XQUERY,即使合并不匹配。因此,f.data 为 NULL,并且转换中的复制表达式得到一个空序列。如果我删除整个“匹配时”子句,则该语句有效。

我做错了什么?或者这是 DB2 的 MERGE 语句的限制?


我试图通过将简单的“匹配时”更改为“匹配时并且(f.data 不为空)”来解决此问题,但这没有任何效果。我还尝试将 XQUERY 表达式更改为以下内容:

if($old)
then
  transform
    copy $out := $old
    ...
else ()

这也没有帮助。我发现的唯一解决方法是将 MERGE 分成两部分。首先我会这样做,以更新 foo 和 foo_incoming 中的行:

merge into foo f
  using
    (
      select q1.id, q1.data
        from foo_incoming q1 inner join foo q2
          on (q1.id = q2.id)
    ) i
  on (f.id = i.id)
  when matched then udpate ...;

然后,插入 foo_incoming 但不在 foo 中的行:

merge into foo f
  using
    (
      select q1.id, q1.data
        from foo_incoming q1 left outer join foo q2
          on (q1.id = q2.id)
        where q2.id is null
    ) i
  on (f.id = i.id)
  when not matched then insert ...;

这行得通。然而,我预计表现会很糟糕。我通常将这种 hack 解释为我的想法存在根本性错误的警告信号。

【问题讨论】:

    标签: merge db2 xquery


    【解决方案1】:

    这可能是 DB2 中应该修复的错误。此处已描述和讨论了相同的问题:

    https://www.ibm.com/developerworks/community/forums/html/topic?id=02fb0ba7-249d-431a-b173-e70511d3b582&ps=25

    我希望即将推出的 DB2 修订包能够解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-17
      • 1970-01-01
      • 2014-01-28
      • 2013-10-03
      • 2020-10-14
      • 2011-06-13
      相关资源
      最近更新 更多