2013-04-25 31 views
0

使用DB2 LUW 10.1。我無法讓MERGE在兩個使用XQUERY轉換合併的XML列的表上工作。使用MERGE和XMLQUERY並轉換

我有一個表,看起來像這樣:

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 
) 

XML列中的數據使用XQUERY變換進行合併。它背後有一些邏輯,所以它不是直接的,但也不是太複雜。我已經測試了使用手動更新的轉換,所以我知道它的工作原理。

然後我嘗試將兩個表合併是這樣的:

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不爲null)時」,但沒有效果。我也嘗試將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 ...; 

這工作。然而,我預計表現會很糟糕。這就是我通常認爲的一種黑客攻擊,表明我的思維存在根本性錯誤。

回答