DB2 SQL更新与子查询相关联

时间:2014-04-05 01:33:12

标签: sql db2 sql-update

代码块:

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所查看的行将被传递到内部查询中。我做错了什么?我得到的例子是:

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
    );

这是作为坏代码的一个例子,但代码应该可以工作。

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

要引用前面的表,请尝试在嵌套表引用中包含LATERAL关键字:

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

没有DB2 9.7实例来测试它,但我认为它应该可以工作。