SQL cara menambah atau mengurangi satu untuk kolom int dalam satu perintah

119

Saya memiliki tabel Pesanan yang memiliki kolom Kuantitas. Saat check in atau check out, kami perlu memperbarui kolom Kuantitas itu satu per satu. Apakah ada cara untuk melakukan ini dalam satu tindakan atau kita harus mendapatkan nilai yang ada dan kemudian menambahkan atau minus satu di atasnya?

Pertanyaan lain adalah ketika kita memasukkan baris baru, apakah kita perlu memeriksa apakah ada data yang sama lalu masukkan jika tidak ada, yang merupakan dua langkah, atau adakah cara yang lebih baik untuk melakukan ini?

Terima kasih,

5YrsLaterDBA
sumber

Jawaban:

250

Untuk menjawab yang pertama:

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

Untuk menjawab yang kedua:

Ada beberapa cara untuk melakukannya. Karena Anda tidak menentukan database, saya akan menganggap 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

Mereka berdua dapat menangani pertanyaan Anda. Namun, sintaks pertama memungkinkan lebih banyak fleksibilitas untuk memperbarui rekaman daripada hanya menggantinya (seperti yang dilakukan yang kedua).

Perlu diingat bahwa agar keduanya ada, harus ada kunci UNIK yang ditentukan ...

gahooa
sumber
32
Karena Anda tidak menentukan database, Anda harus benar-benar mengasumsikan SQL standar.
paxdiablo
12

Jawaban satu langkah untuk pertanyaan pertama adalah dengan menggunakan sesuatu seperti:

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

Itu merupakan cara instruksi tunggal untuk melakukannya.

Adapun pertanyaan kedua, Anda tidak perlu menggunakan senam SQL khusus DBMS (seperti UPSERT) untuk mendapatkan hasil yang Anda inginkan. Ada metode standar untuk melakukan update-or-insert yang tidak memerlukan DBMS tertentu.

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

Artinya, Anda mencoba melakukan penciptaan terlebih dahulu. Jika sudah ada, abaikan kesalahannya. Jika tidak, Anda membuatnya dengan nilai 0.

Kemudian lakukan update yang akan bekerja dengan benar apakah:

  • baris aslinya ada.
  • seseorang memperbaruinya antara sisipan dan pembaruan Anda.

Ini bukan instruksi tunggal, namun, yang cukup mengejutkan, ini adalah cara kami melakukannya dengan sukses untuk waktu yang lama.

paxdiablo
sumber
4

Jika pemahaman saya benar, pembaruan seharusnya cukup sederhana. Saya hanya akan melakukan hal berikut.

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

Anda mungkin memerlukan filter tambahan untuk memperbarui satu baris, bukan semua baris.

Untuk sisipan, Anda dapat menyimpan beberapa id unik yang terkait dengan catatan Anda secara lokal dan memeriksa cache ini dan memutuskan apakah akan menyisipkan atau tidak. Pendekatan alternatifnya adalah selalu menyisipkan dan memeriksa kesalahan pelanggaran PK dan mengabaikannya karena ini adalah penyisipan yang berlebihan.

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

Sejauh yang saya tahu tidak ada built-in dukungan untuk INSERT-OR-UPDATE di SQL. Saya menyarankan untuk membuat prosedur tersimpan atau menggunakan kueri bersyarat untuk mencapai ini. Di sini Anda dapat menemukan kumpulan solusi untuk database yang berbeda.

Daniel Brückner
sumber
Anda mungkin mendapatkan kesalahan sintaks saat melempar kata ORDER yang dipesan seperti itu ...
gahooa
0

untuk menjawab yang kedua:

buat kolom unik dan tangkap pengecualian jika disetel ke nilai yang sama.

dotjoe
sumber
0

@dotjoe Lebih murah untuk memperbarui dan memeriksa @@ rowcount, lakukan penyisipan setelah fakta.

Pengecualian mahal && update lebih sering

Saran: Jika Anda ingin menjadi uber performant di DAL Anda, buat front end pass dalam ID unik untuk baris yang akan diperbarui, jika sisipan null.

DAL harus CRUD, dan tidak perlu khawatir menjadi stateless.

Jika Anda menjadikannya stateless, Dengan indeks yang baik, Anda tidak akan melihat perbedaan dengan pernyataan SQL vs 1 berikut. IF (pilih top 1 * form x dimana PK = @ ID) Masukkan update lain

brian chandley
sumber