SQL วิธีเพิ่มหรือลดหนึ่งสำหรับคอลัมน์ int ในคำสั่งเดียว


119

ฉันมีตารางคำสั่งซื้อซึ่งมีคอลัมน์ปริมาณ ในระหว่างการเช็คอินหรือเช็คเอาต์เราจำเป็นต้องอัปเดตคอลัมน์ปริมาณนั้นทีละคอลัมน์ มีวิธีทำสิ่งนี้ในการกระทำเดียวหรือเราต้องรับค่าที่มีอยู่แล้วบวกหรือลบหนึ่งด้านบน?

อีกคำถามคือเมื่อเราแทรกแถวใหม่เราจำเป็นต้องตรวจสอบว่ามีข้อมูลเดิมหรือไม่จากนั้นจึงแทรกซึ่งเป็นสองขั้นตอนหรือมีวิธีที่ดีกว่านี้หรือไม่?

ขอบคุณ

คำตอบ:


250

เพื่อตอบคำถามแรก:

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

ในการตอบคำถามที่สอง:

มีหลายวิธีในการดำเนินการนี้ เนื่องจากคุณไม่ได้ระบุฐานข้อมูลฉันจะถือว่า 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

ทั้งคู่สามารถจัดการกับคำถามของคุณได้ อย่างไรก็ตามไวยากรณ์แรกช่วยให้อัปเดตเร็กคอร์ดได้อย่างยืดหยุ่นมากขึ้นแทนที่จะแทนที่เพียงอย่างเดียว (เหมือนอย่างที่สองทำ)

โปรดทราบว่าเพื่อให้ทั้งสองมีอยู่จะต้องมีคีย์ที่ไม่ซ้ำกันที่กำหนดไว้ ...


32
เนื่องจากคุณไม่ได้ระบุฐานข้อมูลคุณควรถือว่า SQL มาตรฐานจริงๆ
paxdiablo

12

คำตอบขั้นตอนเดียวสำหรับคำถามแรกคือการใช้สิ่งต่างๆเช่น:

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

นั่นเป็นวิธีการสอนเพียงครั้งเดียวอย่างมาก

สำหรับคำถามที่สองคุณไม่จำเป็นต้องใช้ยิมนาสติก SQL เฉพาะ DBMS (เช่นUPSERT) เพื่อให้ได้ผลลัพธ์ที่คุณต้องการ มีวิธีมาตรฐานในการอัปเดตหรือแทรกที่ไม่ต้องใช้ 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)

เท่าที่ฉันรู้ว่าไม่มีการสนับสนุนในตัวสำหรับ INSERT-OR-UPDATE ใน SQL ฉันขอแนะนำให้สร้างกระบวนงานที่เก็บไว้หรือใช้แบบสอบถามแบบมีเงื่อนไขเพื่อให้บรรลุสิ่งนี้ ที่นี่คุณจะพบชุดโซลูชันสำหรับฐานข้อมูลต่างๆ


คุณอาจได้รับข้อผิดพลาดทางไวยากรณ์ในการโยนคำสงวน ORDER ไปรอบ ๆ เช่นนั้น ...
gahooa

0

เพื่อตอบคำถามที่สอง:

ทำให้คอลัมน์ไม่ซ้ำกันและรับข้อยกเว้นหากตั้งค่าเป็นค่าเดียวกัน


0

@dotjoe มีราคาถูกกว่าในการอัปเดตและตรวจสอบ @@ rowcount ทำการแทรกหลังจากนั้นข้อเท็จจริง

ข้อยกเว้นคือการอัปเดต && ที่มีราคาแพงบ่อยกว่า

คำแนะนำ: หากคุณต้องการเป็นนักแสดงที่ยอดเยี่ยมใน DAL ของคุณให้ส่งผ่านส่วนหน้าใน ID เฉพาะสำหรับแถวที่จะอัปเดตหากใส่ค่าว่าง

DAL ควรเป็น CRUD และไม่จำเป็นต้องกังวลเกี่ยวกับการไร้สัญชาติ

หากคุณทำให้มันไร้สถานะด้วยดัชนีที่ดีคุณจะไม่เห็นความแตกต่างกับคำสั่ง SQL vs 1 ต่อไปนี้ IF (เลือกอันดับ 1 * แบบฟอร์ม x โดยที่ PK = @ ID) แทรกการอัปเดตอื่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.