Postgre에서 외부 키가 있는 행 삭제SQL
외부 키가 포함된 행을 삭제하고 싶지만 다음과 같은 작업을 시도할 때:
DELETE FROM osoby WHERE id_osoby='1'
나는 다음과 같은 진술을 받습니다.
오류: "osoby" 테이블의 업데이트 또는 삭제가 "kontakty" 테이블의 외부 키 제약 조건 "kontakty_ibfk_1"을(를) 위반합니다. detail: 키(id_osoby)=(1)는 여전히 "kontakty" 테이블에서 참조됩니다.
이 행을 삭제하려면 어떻게 해야 합니까?
이를 자동화하기 위해 외부 키 제약 조건을 다음과 같이 정의할 수 있습니다.ON DELETE CASCADE
.
외부 키 제약 조건에 대한 설명서를 인용합니다.
CASCADE
참조된 행을 삭제할 때 해당 행을 참조하는 행도 자동으로 삭제되도록 지정합니다.
다음과 같이 현재 FK 정의를 검색합니다.
SELECT pg_get_constraintdef(oid) AS constraint_def
FROM pg_constraint
WHERE conrelid = 'public.kontakty'::regclass -- assuming public schema
AND conname = 'kontakty_ibfk_1';
그런 다음 추가 또는 수정ON DELETE ...
의 일부.ON DELETE CASCADE
(다른 모든 것을 그대로 보존) 다음과 같은 성명서에서:
ALTER TABLE kontakty
DROP CONSTRAINT kontakty_ibfk_1
, ADD CONSTRAINT kontakty_ibfk_1
FOREIGN KEY (id_osoby) REFERENCES osoby (id_osoby) ON DELETE CASCADE;
거기에는 없다ALTER CONSTRAINT
지휘권제약 조건을 하나로 삭제하고 다시 만들기ALTER TABLE
동시 쓰기 액세스로 발생할 수 있는 레이스 조건을 방지하기 위한 명령문입니다.
분명히 그렇게 하기 위해서는 특권이 필요합니다.작업에 필요한 시간:ACCESS EXCLUSIVE
테이블에 고정된kontakty
그리고 aSHARE ROW EXCLUSIVE
테이블에 고정된osoby
.
할 수 없다면,ALTER
테이블, 수동(한 번) 또는 트리거에 의해 삭제BEFORE DELETE
(매번)이 나머지 옵션입니다.
일반적인 솔루션으로 권장해서는 안 되지만, 운영되지 않거나 현재 사용 중인 데이터베이스의 행을 일회성으로 삭제하는 경우 해당 테이블에서 트리거를 일시적으로 비활성화할 수 있습니다.
저의 경우 개발 모드에 있으며 외부 키를 통해 서로를 참조하는 테이블이 몇 개 있습니다.따라서 내용을 삭제하는 것은 한 테이블에서 다른 테이블 앞에 있는 모든 행을 삭제하는 것만큼 간단하지 않습니다.그래서, 저는 다음과 같이 그들의 내용을 삭제하는 것이 잘 작동했습니다.
ALTER TABLE table1 DISABLE TRIGGER ALL;
ALTER TABLE table2 DISABLE TRIGGER ALL;
DELETE FROM table1;
DELETE FROM table2;
ALTER TABLE table1 ENABLE TRIGGER ALL;
ALTER TABLE table2 ENABLE TRIGGER ALL;
물론 데이터베이스의 무결성을 손상시키지 않도록 주의하면서 원하는 대로 WHERE 절을 추가할 수 있어야 합니다.
http://www.openscope.net/2012/08/23/subverting-foreign-key-constraints-in-postgres-or-mysql/ 에서 관련된 좋은 토론이 있습니다.
외부 키가 여전히 다른 테이블을 참조하는 경우 삭제할 수 없습니다.먼저 참조를 삭제합니다.
delete from kontakty
where id_osoby = 1;
DELETE FROM osoby
WHERE id_osoby = 1;
이 질문을 받은 지 오래되었는데, 희망이 도움이 될 수 있습니다.DB 구조를 변경하거나 변경할 수 없으므로 이 작업을 수행할 수 있습니다.postgresql 문서에 따르면.
잘라내기 - 표 또는 표 집합을 비웁니다.
TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ]
[ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]
묘사
잘라내기는 테이블 집합에서 모든 행을 빠르게 제거합니다.각 테이블에서 정규화되지 않은 DELETE와 동일한 효과를 가지지만 실제로 테이블을 스캔하지 않기 때문에 더 빠릅니다.또한 이후 진공 작업을 수행할 필요 없이 디스크 공간을 즉시 회수합니다.이것은 큰 테이블에서 가장 유용합니다.
테이블 다른 테이블을 잘라내고 외부 키 제약 조건을 통해 다른 테이블을 참조하는 테이블로 캐스케이드합니다.
TRUNCATE othertable CASCADE;
마찬가지로 연결된 시퀀스 생성기도 재설정합니다.
TRUNCATE bigtable, fattable RESTART IDENTITY;
연결된 시퀀스 생성기를 잘라내고 재설정합니다.
TRUNCATE revinfo RESTART IDENTITY CASCADE ;
그것은 표에 있는 것을 의미합니다.kontakty
는하행있다습니이조행에 행을 .osoby
삭제할 항목입니다.먼저 해당 행을 삭제하거나 테이블 간의 관계에 대해 계단식 삭제를 설정해야 합니다.
파우드제니아!
를 통해 관련 레코드를 삭제하는 추가 SQL 스크립트를 실행하면 이를 달성할 수 있습니다.FK
.
위해 를이 위다음사선용의 합니다.WHERE
의 절DELETE
명령은 필요한 것을 간단히 수행할 수 있습니다.
다음과 유사한 것:
DELETE FROM kontakty
WHERE fk_column_from_kontakty_matching_id_osoby IN (
SELECT id_osoby FROM osoby WHERE id_osoby = '1'
);
DELETE FROM osoby WHERE id_osoby = '1';
- 이 예는 다음을 가정합니다.
FK
의 열kontakty
합osoby.id_osoby
를 합다니고라고 합니다.fk_column_from_kontakty_matching_id_osoby
수 입니다. - OP의 경우 쿼리가 많이 단순화될 수 있지만, 더 복잡한 시나리오를 달성하는 것을 보여주기 때문에 이렇게 남겨두기로 결정했습니다.
- 방식은 된 SQL 할 수 유용합니다.
id
그리고 어디서id
s는 먼저 쉽게 가져올 수 없고 나중에 실행될 수 없습니다.
언급URL : https://stackoverflow.com/questions/14182079/delete-rows-with-foreign-key-in-postgresql
'programing' 카테고리의 다른 글
페이지 앵커에 해시태그를 사용한 Angular2 라우팅 (0) | 2023.05.07 |
---|---|
분기의 내용을 새 로컬 분기로 복사하려면 어떻게 해야 합니까? (0) | 2023.05.07 |
애저 데브옵스 파이프라인에서 사용자 환경 변수를 설정하고 읽는 방법은 무엇입니까? (0) | 2023.05.07 |
Postgres에서 모든 테이블의 행 수를 어떻게 찾습니까? (0) | 2023.05.07 |
SQL Server의 IsNull() 함수에 해당하는 C# (0) | 2023.05.07 |