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

둘 다 귀하의 질문을 처리 할 수 ​​있습니다. 그러나 첫 번째 구문을 사용하면 레코드를 대체하는 것보다 더 유연하게 레코드를 업데이트 할 수 있습니다 (두 번째 구문과 마찬가지로).

둘 다 존재하려면 UNIQUE 키가 정의되어 있어야합니다.


32
데이터베이스를 지정하지 않았으므로 실제로 표준 SQL을 가정해야합니다.
paxdiablo

12

첫 번째 질문에 대한 단일 단계 대답은 다음과 같은 것을 사용하는 것입니다.

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

그것은 그것을 수행하는 단일 지시 방법입니다.

두 번째 질문에 대해서는 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

두 번째 대답 :

열을 고유하게 만들고 동일한 값으로 설정된 경우 예외를 포착하십시오.


0

@dotjoe @@ rowcount를 업데이트하고 확인하는 것이 더 저렴하며 그 후에 삽입을 수행하십시오.

예외는 비싸고 업데이트는 더 자주 발생합니다.

제안 : DAL에서 뛰어난 성능을 발휘하려면 null 삽입 인 경우 업데이트 할 행의 고유 ID를 프런트 엔드에 전달합니다.

DAL은 CRUD 여야하며 상태 비 저장에 대해 걱정할 필요가 없습니다.

상태 비 저장으로 만들면 좋은 인덱스를 사용하면 다음 SQL 대 1 문과의 차이점이 표시되지 않습니다. IF (상위 1 * 양식 x, 여기서 PK = @ ID 선택) 삽입 else 업데이트

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.