SQL как увеличить или уменьшить один для столбца int в одной команде - PullRequest
104 голосов
/ 10 июня 2009

У меня есть таблица заказов, в которой есть столбец Количество. Во время заезда или выезда нам нужно обновить этот столбец Количество на единицу. Есть ли способ сделать это за одно действие, или мы должны получить существующее значение, а затем добавить или минус один поверх него?

Другой вопрос: когда мы вставляем новую строку, нужно ли нам проверять, существуют ли одни и те же данные, затем вставлять, если нет, то есть два шага или есть лучший способ сделать это?

спасибо,

Ответы [ 6 ]

223 голосов
/ 10 июня 2009

Чтобы ответить на первый вопрос:

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

Они оба могут ответить на ваш вопрос. Однако первый синтаксис позволяет более гибко обновлять запись, а не просто заменять ее (как второй).

Имейте в виду, что для того, чтобы оба существовали, должен быть определен УНИКАЛЬНЫЙ ключ ...

11 голосов
/ 10 июня 2009

Одношаговый ответ на первый вопрос - использовать что-то вроде:

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

Это очень простой способ сделать это.

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

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

То есть вы сначала пытаетесь сделать творение. Если он уже есть, игнорируйте ошибку. В противном случае вы создаете его со значением 0.

Затем выполните обновление, которое будет работать правильно, независимо от того,

  • строка изначально существовала.
  • кто-то обновил его между вставкой и обновлением.

Это не единственная инструкция, и все же, как ни странно, это то, как мы успешно выполняли ее долгое время.

3 голосов
/ 10 июня 2009
UPDATE Orders Order
SET Order.Quantity =  Order.Quantity - 1
WHERE SomeCondition(Order)

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

2 голосов
/ 10 июня 2009

Если я правильно понимаю, обновления должны быть довольно простыми. Я бы просто сделал следующее.

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

Вам могут понадобиться дополнительные фильтры, чтобы просто обновить одну строку вместо всех строк.

Для вставок вы можете локально кэшировать какой-то уникальный идентификатор, связанный с вашей записью, проверить этот кеш и решить, вставлять или нет. Альтернативный подход заключается в том, чтобы всегда вставлять и проверять наличие ошибок PK и игнорировать, поскольку это избыточная вставка.

0 голосов
/ 10 июня 2009

@ dotjoe Дешевле обновить и проверить @@ rowcount, сделайте вставку после этого факта.

Исключения составляют дорогостоящие && обновления происходят чаще

Предложение: Если вы хотите быть более производительным в вашем DAL, передайте переднему концу уникальный идентификатор для обновляемой строки, если вставьте ноль.

DAL должны быть CRUD, и не нужно беспокоиться о том, что они не имеют статуса.

Если вы сделаете это без сохранения состояния, с хорошими индексами вы не увидите diff со следующим оператором SQL vs 1. IF (выберите верхнюю 1 * форму x, где PK = @ ID) Вставить еще обновление

0 голосов
/ 10 июня 2009

ответить на второе:

делает столбец уникальным и перехватывает исключение, если для него установлено то же значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...