SQL 1つのコマンドでint列の1つを増減する方法


119

数量列のある注文テーブルがあります。チェックインまたはチェックアウト中に、その「数量」列を1つずつ更新する必要があります。これを1つのアクションで実行する方法はありますか、または既存の値を取得してからその上に1を加算または減算する必要がありますか?

別の質問は、新しい行を挿入するときに、同じデータが存在するかどうかを確認してから、存在しない場合に挿入する必要があるかどうかです。これは2つのステップです。

ありがとう

回答:


250

最初に答えるには:

UPDATE Orders SET Quantity = Quantity + 1 WHERE ...

2番目に答えるには:

これを行うにはいくつかの方法があります。データベースを指定しなかったので、MySQLを想定します。

  1. INSERT INTO table SET x=1, y=2 ON DUPLICATE KEY UPDATE x=x+1, y=y+2
  2. REPLACE INTO table SET x=1, y=2

どちらもあなたの質問に対応できます。ただし、最初の構文では、(2番目の構文のように)単にレコードを置き換えるのではなく、レコードを更新する柔軟性が高くなります。

両方が存在するためには、一意のキーが定義されている必要があることに注意してください...


32
データベースを指定しなかったので、実際には標準SQLを想定する必要があります。
paxdiablo 2009年

12

最初の質問に対する単一ステップの回答は、次のようなものを使用することです。

update TBL set CLM = CLM + 1 where key = 'KEY'

それは非常に単一の命令による方法です。

2番目の質問については、目的のUPSERT結果を得るために、DBMS固有のSQL体操(など)に頼る必要はありません。特定のDBMSを必要としない、更新または挿入を行うための標準的な方法があります。

try:
    insert into TBL (key,val) values ('xyz',0)
catch:
    do nothing
update TBL set val = val + 1 where key = 'xyz'

つまり、最初に作成を試みます。すでにそこにある場合は、エラーを無視してください。それ以外の場合は、値0で作成します。

次に、更新が正常に機能するかどうかを実行します。

  • 行は元々存在していました。
  • 挿入と更新の間に誰かが更新しました。

これは単一の指示ではありませんが、驚くことに十分長い間、私たちが長い間成功してきた方法です。


4

私の理解が正しければ、更新はかなり単純なはずです。私は次のようにします。

UPDATE TABLE SET QUANTITY = QUANTITY + 1 and
UPDATE TABLE SET QUANTITY = QUANTITY - 1 where QUANTITY > 0

すべての行ではなく単一の行を更新するには、追加のフィルターが必要になる場合があります。

挿入の場合、レコードに関連する一意のIDをローカルにキャッシュし、このキャッシュと照合して挿入するかどうかを決定できます。代替のアプローチは、常に挿入してPK違反エラーをチェックし、これは冗長な挿入であるため無視します。


4
UPDATE Orders Order
SET Order.Quantity =  Order.Quantity - 1
WHERE SomeCondition(Order)

私の知る限り、SQLのINSERT-OR-UPDATEの組み込みサポートはありません。これを実現するには、ストアドプロシージャを作成するか、条件付きクエリを使用することをお勧めします。ここでは、さまざまなデータベースのソリューションのコレクションを見つけることができます。


予約語ORDERをそのようにスローすると構文エラーが発生する可能性があります...
gahooa

0

2番目に答えるには:

列を一意にし、同じ値に設定されている場合は例外をキャッチします。


0

@dotjoe @@ rowcountを更新して確認し、その後に挿入を行う方が安上がりです。

例外は高価であり、更新はより頻繁です

提案:DALでパフォーマンスを高めたい場合は、更新する行の一意のIDでフロントエンドパスを作成します(ヌル挿入の場合)。

DALはCRUDでなければならず、ステートレスであることを心配する必要はありません。

ステートレスにすると、適切なインデックスを使用すると、次のSQLと1のステートメントの違いがわかりません。IF(トップ1を選択*フォームxでPK = @ IDを挿入)その他の更新を挿入

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.