Question

Code block:

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 ....

My issue is thus: upon execution of the above code, I get 'SQL0204N "PX.YEAR" is an undefined name. SQLSTATE=42704'. I was under the impression that in this case, the row being looked at by update would be passed into the inner query. What have I done wrong? The example I was given was:

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

which was given as an example of bad code, but code that should work nonetheless.

Was it helpful?

Solution

A quick test with DB2 (9.7 LUW) reveals that this works within one level of subquery, but not more than one. This works:

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

This does not work:

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

Why is this? Who knows. It is just one of many mysteries of DB2 syntax.

In any case, this is a bad style of coding (just like the person who gave you the example implied). You should use MERGE when you want to do an update based on the contents of other tables:

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

OTHER TIPS

To reference preceding tables, try including the LATERAL keyword in the nested table reference:

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

Don't have a DB2 9.7 instance to test it but I think it should work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top