2012-01-04 12 views
4

で、私はSELECT FROM UPDATEを実行して、更新+選択を1回のトランザクションで行う必要があります。
しかし、トランザクションごとにというレコードを1つだけ更新してにする必要があります。DB2でレコードを1つだけ更新するには?

MySQL's UPDATEオプション

場所私はDB2's UPDATE referenceで似たようなのためではなく、成功せずに見

を更新できる行数の制限からLIMIT句に泊まっ

どのようにDB2で同様のことが達成できますか?


編集:私のシナリオでは、私は、要求に応じて1000のクーポンコードを提供する必要があります。私は、まだ与えられていないものを選択するだけです。

+3

なぜ更新する行の主キーを含む 'WHERE'条件を追加しないのですか? –

+2

私はあまりにも_random_、個々の行を更新して(それは本質的に)何かを疑うでしょう –

+0

私のシナリオでは、要求に応じて1kのクーポンコードを送付しなければならないので、まだ与えられていないものを選択する必要があります。 –

答えて

3

質問には、何が達成される必要があるか不明確なあいまいな用語が使用されています。幸いにも、DB2はさまざまなSQLパターンを強力にサポートしています。

UPDATEによって変更される行の数を制限するには:UPDATE文はベーステーブル、それをフィルタリングだけで式を見たことがないので、あなたが行を更新するかを制御することができます

UPDATE 
(SELECT t.column1 FROM someschema.sometable t WHERE ... FETCH FIRST ROW ONLY 
) 
SET column1 = 'newvalue'; 

を。新しい行の


INSERTに限定数:

SELECT column1 FROM NEW TABLE (
    UPDATE (SELECT column1 FROM someschema.sometable 
      WHERE ... FETCH FIRST ROW ONLY 
    ) 
    SET column1 = 'newvalue' 
) AS x; 

SELECTはデータを返します。

INSERT INTO mktg.offeredcoupons(cust_id, coupon_id, offered_on, expires_on) 
SELECT c.cust_id, 1234, CURRENT TIMESTAMP, CURRENT TIMESTAMP + 30 DAYS 
FROM mktg.customers c 
LEFT OUTER JOIN mktg.offered_coupons o 
ON o.cust_id = c.cust_id 
WHERE .... 
AND o.cust_id IS NULL 
FETCH FIRST 1000 ROWS ONLY; 


これは、DB2は UPDATEINSERT、または DELETEの文から SELECTをサポートする方法であります変更された行のみ。

+0

DB2の場合、最初のコードブロックでは、 't t'はサブクエリの外側でスコープされないため、' SET t.column1 = 'newvalue''は実際には 'SET column1 =' newvalue''です。 * PS:そのようなアップデートが可能であるかどうかわからなかった!名誉!* – ADTC

+1

いいキャッチ、@ADTC。私はそのコードサンプルを修正しました。 –

2

2つのオプションがあります。 A Horse With No Nameのように、表の主キーを使用して、一度に1つの行が確実に更新されるようにすることができます。

プログラミング言語を使用していてカーソルを制御している場合は、 'FOR UPDATE'オプション付きのカーソルを使用することです(これはおそらくオプションですが、IIRCのカーソルは 'FOR UPDATE'です)。基本となるSELECTが可能であることを意味する場合はデフォルト)、UPDATEステートメントでWHERE CURRENT OF <cursor-name>のUPDATEステートメントを使用します。カーソルによって現在アドレス指定されている1行が更新されます。構文の詳細は、使用している言語と異なりますが、生のSQLは次のようになります。

DECLARE CURSOR cursor_name FOR 
    SELECT * 
     FROM SomeTable 
    WHERE PKCol1 = ? AND PKCol2 = ? 
     FOR UPDATE; 

UPDATE SomeTable 
    SET ... 
WHERE CURRENT OF cursor_name; 

あなたのホスト言語でDECLAREを書き込むことができない場合は、同等のものを見つけるために、手動でバッシングをしなければなりません機構。

+0

あなたのcusorがブロッキング(全行セットを返す)を利用するように定義されていて、(行ポインタの位置のために)現在のブロックの_last_行だけを更新するならば、 。 –

+0

ありがとう、@ X-Zero;私は「WHERE CURRENT OF」を壊す方法があることに気づいていませんでした。どのオプションがあるかは驚くべきことです。これは、物事を行うための恐ろしい良い方法ではありません。私は主キーを検索してレコードを更新することをお勧めします。それはWHERE CURRENT OFなどの手法よりも「遅い」ですが。 –

関連する問題