Thanks to Serge Rielau for insight in DB2 MERGE.
For example, if you have this Oracle UPDATE statement and wondering how can you use this in DB2. Here is the solution.
Oracle UPDATE
UPDATE
(
SELECT clm.c2 wc1,
m.c2 wc2
FROM schema1.table1 m,
schema1.table2 clm
WHERE clm.c1 = m.c1
and clm.date1 between to_date('10012008','MMDDYYYY') and to_date('12312008','MMDDYYYY')
and m.date2 between to_date('10012008','MMDDYYYY') and to_date('12312008','MMDDYYYY')
and m.flag = 'N'
) joined
SET joined.wc1 = joined.wc2;
DB2 Merge
MERGE INTO schema1.table1 m
USING schema1.table2 clm
ON clm.c1 = m.c1
and clm.date1 between to_date('10012008','MMDDYYYY') and to_date('12312008','MMDDYYYY')
and m.date2 between to_date('10012008','MMDDYYYY') and to_date('12312008','MMDDYYYY')
and m.flag = 'N'
WHEN MATCHED THEN UPDATE SET m.c2 = clm.c2;
SQL Server Update – 2 table issue
update t set book = r.book from #RecLookup r JOIN TABLE_TOBE_UPDATED t ON t.history_date = CONVERT ( char(8) , @CobDate, 112) and t.rec_id = r.rec_id where (r.update_options & 0x1) = 0x1 AND ((@MinRecId = 0 and @MaxRecId = 0x7FFFFFFF) OR (t.rec_id >= CONVERT(varchar(12),@MinRecId) and t.rec_id <= CONVERT(varchar(12),@MaxRecId)))
DB2 using MERGE
MERGE INTO TABLE_TOBE_UPDATED T
USING SESSION.TT_RECLOOKUP R
ON T.HISTORY_DATE = V_COBDATE
AND T.REC_ID = R.REC_ID
AND (BITAND(R.UPDATE_OPTIONS,1)) = 1
AND ((V_MINRECID = 0 AND V_MAXRECID = 2147483647) OR
(T.REC_ID >= V_MINRECID AND T.REC_ID <= V_MAXRECID))
WHEN MATCHED THEN UPDATE SET
T.BOOK = R.BOOK;
Or, another MERGE. The explain plan will tell you which one is better.
MERGE INTO
(
SELECT REC_ID, BOOK FROM TABLE_TOBE_UPDATED
WHERE HISTORY_DATE = V_COBDATE
AND ((V_MINRECID = 0 AND V_MAXRECID = 2147483647) OR
(REC_ID >= V_MINRECID AND REC_ID <= V_MAXRECID))
) AS T
USING
(
SELECT REC_ID, BOOK FROM SESSION.TT_RECLOOKUP
WHERE (BITAND(UPDATE_OPTIONS,1)) = 1
) AS R
ON T.REC_ID = R.REC_ID
WHEN MATCHED THEN UPDATE SET
T.BOOK = R.BOOK;
SQL Server UPDATE returning more than one row for each matched row
Take this example of notorious UPDATE in SQL Server where more than one row is returned for each row matched in the table_tobe_updated. This is a feature of SQL Server you realize when porting to DB2. When you try to match this in DB2, you might get -811 error.
The result of a scalar fullselect, SELECT INTO statement, or VALUES INTO statement is more than one row.. SQLCODE=-811, SQLSTATE=21000
SQL Server Update returning more than one row for each matched row
update tmp
set
trading_book_id = bk_Riskmap.book_id,
trading_book_name = bk_Riskmap.book_name,
party_book_name = bk_Riskmap.counterparty_book_name,
party_book_id = bk_Riskmap.counterparty_book_id,
cost_center = bk_Riskmap.cost_center,
Risk_Reason = bk_Riskmap.risk_reason,
mapping_type = (tmp.mapping_type | 0x2)
from TABLE_TOBE_UPDATED tmp
JOIN (
select book_name, edsi_id, book_hist_id = MIN(book_hist_id)
from dbo.book_hist
where history_date = @CobDate
and (options & 0x2) = 0x2
group by book_name, edsi_id
) UList
ON tmp.book = UList.book_name
and tmp.edsi_id = UList.edsi_id
JOIN dbo.book_hist bk_Riskmap
ON bk_Riskmap.history_date = @CobDate
and UList.book_hist_id = bk_Riskmap.book_hist_id
DB2 UPDATE - USING MERGE
MERGE INTO TEMP.TABLE_TOBE_UPDATED TMP
USING
(
SELECT ULIST.BOOK_NAME, ULIST.EDSI_ID, MIN(ULIST.BOOK_HIST_ID) BOOK_HIST_ID
FROM BOOK_HIST UList
WHERE UList.HISTORY_DATE = '2009-03-31'
AND BITAND(UList.OPTIONS,2) = 2
GROUP BY ULIST.BOOK_NAME, ULIST.EDSI_ID
) AS U (BOOK_NAME, EDSI_ID, BOOK_HIST_ID)
ON TMP.BOOK = U.BOOK_NAME
AND TMP.EDSI_ID = U.EDSI_ID
WHEN MATCHED THEN UPDATE SET
(TRADING_BOOK_ID,TRADING_BOOK_NAME,PARTY_BOOK_NAME,
PARTY_BOOK_ID,COST_CENTER,RISK_REASON,MAPPING_TYPE) =
(
SELECT BOOK_ID, BOOK_NAME,
COUNTERPARTY_BOOK_NAME,
COUNTERPARTY_BOOK_ID,
COST_CENTER,
RISK_REASON,
BITOR(TMP.MAPPING_TYPE, 2)
FROM BOOK_HIST BK_RISKMAP
WHERE BK_RISKMAP.HISTORY_DATE = '2009-03-31'
AND U.BOOK_HIST_ID = BK_RISKMAP.BOOK_HIST_ID
)@
Rule of thumb: You should never have to use TARGET table in the USING clause.