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'

Це дуже однозначний спосіб зробити це.

Щодо другого питання, вам не потрібно вдаватися до специфічної для СУБД гімнастики (як UPSERT), щоб отримати бажаний результат. Існує стандартний метод зробити оновлення або вставлення, який не вимагає конкретної СУБД.

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

Можливо, вам знадобляться додаткові фільтри, щоб просто оновити один рядок замість усіх рядків.

Для вставок ви можете кешувати якийсь унікальний ідентифікатор, пов’язаний із вашою записом на локальному рівні, і перевірити, чи є цей кеш і вирішити, вставляти чи ні. Альтернативний підхід полягає у тому, щоб завжди вставляти та перевіряти на помилки порушення ПК та ігнорувати, оскільки це зайва вставка.


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

Наскільки я знаю, немає вбудованої підтримки для INSERT-OR-UPDATE в SQL. Я пропоную створити збережену процедуру або використовувати умовний запит для досягнення цього. Тут ви можете знайти колекцію рішень для різних баз даних.


Ви можете отримати синтаксичну помилку, кидаючи зарезервоване слово ЗАМОВЛЕННЯ так ...
gahooa

0

щоб відповісти на друге:

зробіть стовпець унікальним і зафіксуйте виняток, якщо для нього встановлено те саме значення.


0

@dotjoe Це дешевше оновити та перевірити @@ rowcount, зробіть вставку після факту.

Винятки - дорогі та оновлення && частіші

Рекомендація: Якщо ви хочете стати виконавцем uber у своєму DAL, введіть передній кінець в унікальний ідентифікатор для оновлення рядка, якщо нуль вставляється.

DAL повинні бути CRUD, і не потрібно турбуватися про без громадянство.

Якщо ви зробите його без стану, при хороших індексах ви не побачите розбіжностей із наведеним нижче оператором SQL vs 1. ЯКЩО (виберіть верхню форму 1 * x x, де PK = @ ID) Вставте інше оновлення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.