2014-04-05 166 views
0

代碼塊關聯:DB2 SQL更新子查詢

update yrb_purchase px 
    set px.club = (select club 
        from (select p.title, p.year, o.club, o.price, 
           ROW_NUMBER() OVER(PARTITION BY p.title, p.year 
                ORDER BY o.price 
               ) rn 
          from yrb_purchase 
          inner join yrb_offer o on p.title = o.title 
                and p.year = o.year 
          inner join yrb_member m on m.club = o.club 
          inner join yrb_customer c on c.cid = p.cid 
                and c.cid = m.cid 
          where p.cid = px.cid 
          and p.title = px.title 
          and p.year = px.year 
          order by title 
         ) 
       where rn = 1 
      ) 
where .... 

我的問題是這樣的:在上面的代碼的執行,我得到「SQL0204N‘PX.YEAR’是一個未定義的名稱。 SQLSTATE = 42704' 。我的印象是,在這種情況下,更新查看的行將被傳遞到內部查詢中。我做錯了什麼?我給出的例子是:

update yrb_purchase P 
set club = (
     select min(M.club) 
      from yrb_member M, yrb_offer O 
      where P.cid = M.cid 
       and M.club = O.club 
       and P.title = O.title 
       and P.year = O.year 
    ) 
where 
    club <> (
     select min(M.club) 
      from yrb_member M, yrb_offer O 
      where P.cid = M.cid 
       and M.club = O.club 
       and P.title = O.title 
       and P.year = O.year 
    ); 

這是作爲錯誤代碼的例子給出的,但代碼應該工作。

+0

...爲什麼這是一個壞代碼的例子? iSeries版本不支持'UPDATE's /'DELETE'中的連接,所以這是唯一的方法(禁止臨時表之類的東西)儘管你應該避免隱式連接語法...... –

回答

0

使用DB2(9.7 LUW)進行快速測試表明,這適用於子查詢的一個級別,但不能超過一個。這工作:

update foo f 
    set bar = ( 
     select count(*) from baz where f.bar = baz.bar 
    ) 

這不起作用:

update foo f 
    set bar = ( 
     select count(*) from (
      select * from baz where f.bar = baz.bar 
     ) 
    ) 

這是爲什麼?誰知道。它只是DB2語法的許多祕密之一。

無論如何,這是一種糟糕的編碼風格(就像給你隱含的例子的人一樣)。你應該use MERGE當你要根據其它表的內容做一個更新:

merge into foo f 
    using baz b 
    on foo.bar = baz.bar 
    when matched then update set 
     foo.bar = 123; 
0

要引用前面的表,嘗試包括LATERAL關鍵字嵌套表參考:

update yrb_purchase px 
    set px.club = (select club from LATERAL (select p.title, p.year, o.club, ... 

別沒有DB2 9.7實例來測試它,但我認爲它應該可以工作。