programing

테이블의 행을 업데이트하거나 존재하지 않는 경우 삽입하려면 어떻게 해야 합니까?

kingscode 2022. 9. 27. 21:39
반응형

테이블의 행을 업데이트하거나 존재하지 않는 경우 삽입하려면 어떻게 해야 합니까?

다음 카운터 테이블이 있습니다.

CREATE TABLE cache (
    key text PRIMARY KEY,
    generation int
);

카운터 중 하나를 늘리거나 해당 행이 아직 존재하지 않으면 0으로 설정합니다.표준 SQL에서 동시성 문제 없이 이를 수행할 수 있는 방법이 있습니까?작업은 트랜잭션의 일부이거나 분리될 수 있습니다.

SQLite, Postgre에서 SQL을 변경하지 않고 실행해야 합니다.SQL 및 MySQL(가능한 경우).

검색 결과 동시성 문제로 인해 문제가 발생하거나 데이터베이스에 고유한 여러 가지 아이디어가 발견되었습니다.

  • 노력하다INSERT새로운 행과UPDATE에러가 있었을 경우.불행히도 에러는INSERT현재 트랜잭션을 중단합니다.

  • UPDATE행 및 행이 변경되지 않은 경우INSERT새 줄

  • MySQL에는ON DUPLICATE KEY UPDATE절을 클릭합니다.

편집: 좋은 답변 감사합니다.폴의 말이 맞는 것 같습니다.휴대폰으로 할 수 있는 방법은 단 하나뿐이 아닙니다.아주 기본적인 수술인 것 같은데 놀랍네요.

MySQL(이후 SQLite)은 REPLACE INTO 구문도 지원합니다.

REPLACE INTO my_table (pk_id, col1) VALUES (5, '123');

그러면 기본 키가 자동으로 식별되고 업데이트할 일치하는 행이 검색되며, 찾을 수 없는 경우 새 행을 삽입합니다.

문서: https://dev.mysql.com/doc/refman/8.0/en/replace.html

SQLite는 이 이미 있는 경우 이를 대체할 수 있습니다.

INSERT OR REPLACE INTO [...blah...]

이 값을 다음과 같이 줄일 수 있습니다.

REPLACE INTO [...blah...]

이 바로 가기는 MySQL과 호환되도록 추가되었습니다.REPLACE INTO표현.

저는 다음과 같은 것을 하고 싶습니다.

INSERT INTO cache VALUES (key, generation)
ON DUPLICATE KEY UPDATE (key = key, generation = generation + 1);

코드 또는 SQL에서 생성 값을 0으로 설정하지만,는 ON DUP...를 사용하여 값을 증가시킵니다.어쨌든 그런 구문인 것 같아요.

ON DUPLICATE KEY UPDATE 절이 가장 좋은 해결책입니다.이는 REPLACE가 DELETE를 실행한 후 INSERT를 실행하므로 레코드가 삭제되기 때문에 REPLACE 쿼리 중에 페이지가 표시되었을 경우 쿼리가 다시 돌아올 가능성이 매우 낮기 때문입니다.

INSERT가 더 좋아요...중복 업데이트 시... 이러한 이유로 인해

jmoz의 솔루션이 최고입니다.단, 괄호보다는 SET 구문을 선호합니다.

INSERT INTO cache 
SET key = 'key', generation = 'generation'
ON DUPLICATE KEY 
UPDATE key = 'key', generation = (generation + 1)
;

플랫폼 중립적인 솔루션을 찾을 수 있을지 모르겠습니다.

이것은 일반적으로 "UPSERT"라고 불립니다.

관련 설명을 참조해 주세요.

포스트그레SQL에는 merge 명령어가 없습니다.실제로 이 명령어를 쓰는 것은 간단하지 않습니다.실제로 작업을 "재미있게" 만드는 이상한 엣지 케이스가 있습니다.

가장 좋은 방법(와 같이: 가장 가능한 조건에서 작업)은 수동(merge_db)에 나와 있는 것과 같은 기능을 사용하는 것입니다.

기능을 사용하고 싶지 않은 경우는, 다음의 조작을 피할 수 있습니다.

updated = db.execute(UPDATE ... RETURNING 1)
if (!updated)
  db.execute(INSERT...)

이것은 폴트 프루프가 아니기 때문에, 최종적으로 실패하는 것을 잊지 말아 주세요.

표준 SQL은 이 작업에 대한 MERGE 문을 제공합니다.일부 DBMS는 MERGE 문을 지원하지 않습니다.

(예를 들어 트랜잭션을 통해) 원자적으로 업데이트하거나 삽입하는 일반적인 방법이 없는 경우 다른 잠금 방식으로 폴백할 수 있습니다.0바이트 파일, 시스템 뮤텍스, 명명된 파이프 등...

인서트 트리거를 사용할 수 있습니까?실패할 경우 업데이트를 수행합니다.

SQL을 쓰는 라이브러리를 사용해도 괜찮다면 Upsert를 사용할 수 있습니다(현재는 Ruby와 Python만 해당).

Pet.upsert({:name => 'Jerry'}, :breed => 'beagle')
Pet.upsert({:name => 'Jerry'}, :color => 'brown')

MySQL, Postgres 및 SQLite3에서 사용할 수 있습니다.

MySQL Postgres my my my 、 UDF ( UDF ) 。 it it를 한다.INSERT OR REPLACESQLite3를 사용합니다.

언급URL : https://stackoverflow.com/questions/690632/how-do-i-update-a-row-in-a-table-or-insert-it-if-it-doesnt-exist

반응형