[SQL] 존재하지 않는 경우 어떻게하면 테이블의 행을 갱신 또는 삽입합니까?
SQL존재하지 않는 경우 어떻게하면 테이블의 행을 갱신 또는 삽입합니까?
나는 카운터 다음 표를 가지고 :
CREATE TABLE cache (
key text PRIMARY KEY,
generation int
);
나는 카운터를 증가 싶은, 또는 해당 행이 아직 존재하지 않는 경우 0으로 설정합니다. 표준 SQL에서 동시성 문제없이 할 수있는 방법이 있나요? 동작은 때때로 분리, 때로는 트랜잭션의 일부입니다.
가능하면 SQL은, SQLite는, PostgreSQL의와 MySQL에 수정되지 않은 실행해야합니다.
수색 중 하나 동시성 문제로 고통, 또는 데이터베이스에 고유 한 몇 가지 아이디어를 얻었다 :
편집 : 모든 위대한 답변을 주셔서 감사합니다. 바울은 바로이며,이 일을 하나의 휴대용 방법이 아니다 것 같습니다. 그것은 아주 기본적인 작업 같은 소리로 즉 아주, 나에게 놀라운.
해결법
-
==============================
1.MySQL을 (그리고 이후 SQLite는) 또한 REPLACE INTO 구문을 지원합니다
MySQL을 (그리고 이후 SQLite는) 또한 REPLACE INTO 구문을 지원합니다
REPLACE INTO my_table (pk_id, col1) VALUES (5, '123');
이것은 자동으로 기본 키를 식별하고 아무 것도 발견되지 않으면 새를 삽입, 갱신에 일치하는 행을 찾습니다.
-
==============================
2.이미있는 경우 행을 교체 SQLite는 지원 :
이미있는 경우 행을 교체 SQLite는 지원 :
INSERT OR REPLACE INTO [...blah...]
당신이 단축 될 수 있습니다
REPLACE INTO [...blah...]
이 바로 가기는 MySQL을 표현 INTO 교체와 호환 될 수 있도록 하였다.
-
==============================
3.나는 다음과 같은 일을 할 것입니다 :
나는 다음과 같은 일을 할 것입니다 :
INSERT INTO cache VALUES (key, generation) ON DUPLICATE KEY UPDATE (key = key, generation = generation + 1);
코드 또는 SQL에서 0으로 생성 값을 설정하지만, 값을 증가 할 ... ON DUP를 사용하여. 나는 어쨌든 구문 생각합니다.
-
==============================
4.를 ON DUPLICATE KEY UPDATE 절은 최고의 솔루션으로 인해입니다 : REPLACE는 INSERT 다음에 DELETE 때문에 레코드가 쿼리 페이지가 동안 볼 경우 쿼리를 교체하는 것이 생략 한 돌아올 수 있다는 아무리 약간의 가능성을 만들어 제거하는 아무리 약간의 기간 동안 수행합니다.
를 ON DUPLICATE KEY UPDATE 절은 최고의 솔루션으로 인해입니다 : REPLACE는 INSERT 다음에 DELETE 때문에 레코드가 쿼리 페이지가 동안 볼 경우 쿼리를 교체하는 것이 생략 한 돌아올 수 있다는 아무리 약간의 가능성을 만들어 제거하는 아무리 약간의 기간 동안 수행합니다.
나는 그 이유가 ... INSERT ... ON DUPLICATE UPDATE를 선호합니다.
jmoz의 솔루션은 최고입니다 : 나는 괄호로 SET 구문을 선호하지만
INSERT INTO cache SET key = 'key', generation = 'generation' ON DUPLICATE KEY UPDATE key = 'key', generation = (generation + 1) ;
-
==============================
5.난 당신이 플랫폼 중립적 인 해결책을 찾기 위해려고하고 있다는 것을 모른다.
난 당신이 플랫폼 중립적 인 해결책을 찾기 위해려고하고 있다는 것을 모른다.
이것은 흔히 "UPSERT"라고합니다.
일부 관련 토론을 참조하십시오 :
-
==============================
6.PostgreSQL을 거기에 더 병합 명령 없으며, 실제로 그것을 작성하는 것은 사소한 아니다 - 작업이 "재미"만드는 이상한 가장자리 경우가 실제로있다.
PostgreSQL을 거기에 더 병합 명령 없으며, 실제로 그것을 작성하는 것은 사소한 아니다 - 작업이 "재미"만드는 이상한 가장자리 경우가 실제로있다.
(같이 : 가장 가능한 조건에서 작업) 최고 - 수동 (merge_db)에 표시된 것과 같은 접근 방식은 기능을 사용하는 것입니다.
이 기능을 사용하지 않으려면, 당신은 일반적으로 멀리 얻을 수 있습니다 :
updated = db.execute(UPDATE ... RETURNING 1) if (!updated) db.execute(INSERT...)
그냥 증거 잘못되지 않는다는 것을 기억하고 결국 실패합니다.
-
==============================
7.표준 SQL은이 작업의 MERGE 문을 제공합니다. 모든 DBMS는 MERGE 문을 지원합니다.
표준 SQL은이 작업의 MERGE 문을 제공합니다. 모든 DBMS는 MERGE 문을 지원합니다.
-
==============================
8.당신이 (트랜잭션을 통해 예를 들어) 원자 적으로 갱신 또는 삽입하는 일반적인 방법이없는 경우에 당신은 다른 잠금 방식으로 폴백 할 수 있습니다. 0 바이트 파일 시스템 뮤텍스, 명명 된 파이프, 등 ...
당신이 (트랜잭션을 통해 예를 들어) 원자 적으로 갱신 또는 삽입하는 일반적인 방법이없는 경우에 당신은 다른 잠금 방식으로 폴백 할 수 있습니다. 0 바이트 파일 시스템 뮤텍스, 명명 된 파이프, 등 ...
-
==============================
9.당신은 삽입 트리거를 사용할 수 있을까요? 실패하면, 갱신을한다.
당신은 삽입 트리거를 사용할 수 있을까요? 실패하면, 갱신을한다.
-
==============================
10.당신은 당신을 위해 SQL을 쓰는 라이브러리를 사용하여 함께있을 OK, 당신은 Upsert 사용할 수있는 경우 (현재 루비와 파이썬 만 해당) :
당신은 당신을 위해 SQL을 쓰는 라이브러리를 사용하여 함께있을 OK, 당신은 Upsert 사용할 수있는 경우 (현재 루비와 파이썬 만 해당) :
Pet.upsert({:name => 'Jerry'}, :breed => 'beagle') Pet.upsert({:name => 'Jerry'}, :color => 'brown')
MySQL은, 포스트 그레스, 및 sqlite3를 통해 작동합니다.
그것은 저장 프로 시저 또는 MySQL과 포스트 그레스에서 사용자 정의 기능 (UDF)를 기록한다. 이 INSERT를 사용 또는 sqlite3를에 교체.
from https://stackoverflow.com/questions/690632/how-do-i-update-a-row-in-a-table-or-insert-it-if-it-doesnt-exist by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 페이징 SQL Server 2005의 결과 (0) | 2020.04.23 |
---|---|
[SQL] 은 "@"기호는 SQL의 기능은 무엇입니까? (0) | 2020.04.23 |
[SQL] SQL - 선택 처음 10 행에만? (0) | 2020.04.23 |
[SQL] 두 개의 열을 결합하여 새로운 컬럼에 추가 MYSQL (0) | 2020.04.23 |
[SQL] 임시 쿼리 나 저장 프로 시저 : 어느 것이 나은가? [닫은] (0) | 2020.04.23 |