postgresql로 "무시 삽입" 및 "중복 키 업데이트 시"(sql 병합)를 에뮬레이트하는 방법은 무엇입니까?
일부 SQL 서버에는 다음과 같은 기능이 있습니다.INSERT
기본/오프라인 키 제약 조건을 위반하는 경우 건너뜁니다.예를 들어 MySQL은INSERT IGNORE
.
본받을 수 있는 가장 좋은 방법은 무엇입니까?INSERT IGNORE
그리고.ON DUPLICATE KEY UPDATE
PostgreSQL과 함께?
Postgre 포함SQL 9.5는 이제 기본 기능입니다(MySQL이 몇 년 동안 사용해 온 기능).
삽입...충돌 시 아무것도 하지 않음/업데이트("UPSERT")
9.5는 "UPSERT" 작업을 지원합니다.INSERT는 ON CONCLIVE DO UPDATE/IGNORE 절을 허용하도록 확장되었습니다.이 절은 중복 위반이 발생할 경우 취할 대체 조치를 지정합니다.
...
새로운 구문의 추가 예:
INSERT INTO user_logins (username, logins)
VALUES ('Naomi',1),('James',1)
ON CONFLICT (username)
DO UPDATE SET logins = user_logins.logins + EXCLUDED.logins;
편집: Warren의 답변을 놓쳤을 경우를 대비하여 PG9.5에는 업그레이드 시간이 있습니다!
Bill Karwin의 답변을 바탕으로 규칙 기반 접근 방식(동일한 DB의 다른 스키마에서 다중 열 기본 키로 전송)을 설명합니다.
CREATE RULE "my_table_on_duplicate_ignore" AS ON INSERT TO "my_table"
WHERE EXISTS(SELECT 1 FROM my_table
WHERE (pk_col_1, pk_col_2)=(NEW.pk_col_1, NEW.pk_col_2))
DO INSTEAD NOTHING;
INSERT INTO my_table SELECT * FROM another_schema.my_table WHERE some_cond;
DROP RULE "my_table_on_duplicate_ignore" ON "my_table";
참고: 규칙은 모두에게 적용됩니다.INSERT
규칙이 삭제될 때까지 작업을 수행하므로 특별한 작업은 아닙니다.
Postgres 9.5 이상을 사용하는 사용자에게는 새로운 ON CONCLIVE DO NOTHING 구문이 작동합니다.
INSERT INTO target_table (field_one, field_two, field_three )
SELECT field_one, field_two, field_three
FROM source_table
ON CONFLICT (field_one) DO NOTHING;
이전 버전을 사용하는 사용자에게는 다음과 같은 올바른 가입이 대신 적용됩니다.
INSERT INTO target_table (field_one, field_two, field_three )
SELECT source_table.field_one, source_table.field_two, source_table.field_three
FROM source_table
LEFT JOIN target_table ON source_table.field_one = target_table.field_one
WHERE target_table.field_one IS NULL;
업데이트를 시도합니다.행을 수정하지 않으면 해당 행이 존재하지 않는 경우 삽입을 수행합니다.분명히, 당신은 이것을 거래 안에서 합니다.
클라이언트 측에 추가 코드를 추가하지 않으려면 당연히 함수로 이 코드를 래핑할 수 있습니다.당신은 또한 그러한 생각에서 매우 희귀한 인종 조건에 대한 루프가 필요합니다.
문서에는 이에 대한 예가 나와 있습니다. http://www.postgresql.org/docs/9.3/static/plpgsql-control-structures.html, 예제 40-2는 맨 아래에 있습니다.
그것이 보통 가장 쉬운 방법입니다.규칙으로 마법을 부릴 수는 있지만, 훨씬 더 혼란스러울 것입니다.저는 언제든지 그것보다 기능적으로 랩인 접근법을 추천합니다.
이는 단일 행 또는 소수 행 값에 적용됩니다.예를 들어 하위 쿼리에서 대량의 행을 처리하는 경우에는 두 개의 쿼리로 분할하는 것이 가장 좋습니다. 하나는 INSERT용이고 다른 하나는 UPDATE용입니다(물론 적절한 가입/하위 선택으로 주 필터를 두 번 쓸 필요가 없습니다).
insert ignore 로직을 얻으려면 아래와 같은 작업을 수행합니다.리터럴 값의 선택 문에서 단순히 삽입하는 것이 가장 효과적이라는 것을 알게 되었습니다. 그러면 존재하지 않음 절을 사용하여 중복 키를 마스킹할 수 있습니다.중복 로직에 대한 업데이트를 받으려면 pl/pgsql 루프가 필요할 것 같습니다.
INSERT INTO manager.vin_manufacturer
(SELECT * FROM( VALUES
('935',' Citroën Brazil','Citroën'),
('ABC', 'Toyota', 'Toyota'),
('ZOM',' OM','OM')
) as tmp (vin_manufacturer_id, manufacturer_desc, make_desc)
WHERE NOT EXISTS (
--ignore anything that has already been inserted
SELECT 1 FROM manager.vin_manufacturer m where m.vin_manufacturer_id = tmp.vin_manufacturer_id)
)
INSERT INTO mytable(col1,col2)
SELECT 'val1','val2'
WHERE NOT EXISTS (SELECT 1 FROM mytable WHERE col1='val1')
@hanmari가 그의 논평에서 언급했듯이.postgres 테이블에 삽입할 때, on conflict (...) do nothing은 중복 데이터를 삽입하지 않는 데 사용하기에 가장 좋은 코드입니다.:
query = "INSERT INTO db_table_name(column_name)
VALUES(%s) ON CONFLICT (column_name) DO NOTHING;"
코드의 ON CONCLIVEL 행을 사용하면 삽입 문에서 데이터 행을 계속 삽입할 수 있습니다.쿼리 및 값 코드는 Excel의 날짜를 postgres db 테이블에 삽입한 예입니다.ID 필드가 고유한지 확인하기 위해 사용하는 사후 테이블에 제약 조건이 추가되었습니다.동일한 데이터 행에 대해 삭제를 실행하는 대신 ID 열 번호를 1부터 다시 지정하는 SQL 코드 행을 추가합니다.예:
q = 'ALTER id_column serial RESTART WITH 1'
데이터에 ID 필드가 있는 경우 이 필드를 기본 ID/일련 ID로 사용하지 않고 ID 열을 만들어 일련으로 설정합니다.이 정보가 모두에게 도움이 되길 바랍니다.*저는 소프트웨어 개발/코딩 분야에서 대학 학위가 없습니다.코딩에서 제가 아는 모든 것은 제 스스로 공부합니다.
Postgre처럼 보입니다.SQL은 규칙이라는 스키마 개체를 지원합니다.
http://www.postgresql.org/docs/current/static/rules-update.html
수 .ON INSERT
주어진 테이블에 대해, 그것을 하게 합니다.NOTHING
주 키 값을 하게 하는 UPDATE
INSERT
지정된 기본 키 값을 가진 행이 있는 경우.
저는 이것을 직접 시도해 본 적이 없기 때문에 경험으로 말하거나 예를 들어줄 수 없습니다.
이 솔루션은 규칙 사용을 방지합니다.
BEGIN
INSERT INTO tableA (unique_column,c2,c3) VALUES (1,2,3);
EXCEPTION
WHEN unique_violation THEN
UPDATE tableA SET c2 = 2, c3 = 3 WHERE unique_column = 1;
END;
그러나 성능에는 단점이 있습니다(Postgre 참조).SQL.org ):
예외 절이 포함된 블록은 없는 블록보다 들어가고 나오는 데 훨씬 더 많은 비용이 듭니다.따라서 필요 없이 예외를 사용하지 마십시오.
대량으로 삽입 전 행을 항상 삭제할 수 있습니다.존재하지 않는 행을 삭제해도 오류가 발생하지 않으므로 안전하게 건너뜁니다.
데이터 가져오기 스크립트의 경우 "을(를) 바꾸십시오.만약 존재하지 않는다면"이라는 표현은, 어떤 면에서, 그럼에도 불구하고 작동하는 약간 어색한 공식이 있습니다.
DO
$do$
BEGIN
PERFORM id
FROM whatever_table;
IF NOT FOUND THEN
-- INSERT stuff
END IF;
END
$do$;
언급URL : https://stackoverflow.com/questions/1009584/how-to-emulate-insert-ignore-and-on-duplicate-key-update-sql-merge-with-po
'programing' 카테고리의 다른 글
탐색 모음에서 뒤로 단추 색 변경 (0) | 2023.05.07 |
---|---|
정수로 캐스트 문자열 입력 (0) | 2023.05.07 |
"모호한 리디렉션" 오류를 가져오는 중 (0) | 2023.05.07 |
예외가 있는 Python 유형 암시 (0) | 2023.05.07 |
VBA의 멀티스레딩 (0) | 2023.05.07 |