Programing

PostgreSQL에서 외래 키가있는 행 삭제

lottogame 2020. 12. 15. 08:11
반응형

PostgreSQL에서 외래 키가있는 행 삭제


외래 키를 포함하는 행을 삭제하고 싶지만 다음과 같이 시도 할 때 :

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 pubic 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테이블에 잠금 kontaktySHARE ROW EXCLUSIVE테이블에 잠금을 osoby.

ALTER테이블 을 볼 수없는 경우 손으로 (한 번) 또는 트리거 BEFORE DELETE(매번 )로 삭제하는 것이 나머지 옵션입니다.


여전히 다른 테이블을 참조하는 경우 외래 키를 삭제할 수 없습니다. 먼저 참조 삭제

delete from kontakty
where id_osoby = 1;

DELETE FROM osoby 
WHERE id_osoby = 1;

이를 일반적인 솔루션으로 권장해서는 안되지만 프로덕션 상태가 아니거나 활성 상태가 아닌 데이터베이스의 행을 일회성으로 삭제하려면 해당 테이블에서 트리거를 일시적으로 비활성화 할 수 있습니다.

제 경우에는 개발 모드에 있으며 외래 키를 통해 서로를 참조하는 두 개의 테이블이 있습니다. 따라서 내용을 삭제하는 것은 한 테이블에서 다른 테이블보다 먼저 모든 행을 제거하는 것만 큼 간단하지 않습니다. 그래서 나를 위해 다음과 같이 내용을 삭제하는 것이 잘 작동했습니다.

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/에 좋은 관련 토론이 있습니다 .


이 질문을 한 지 오래되었습니다. 희망이 도움이 될 수 있습니다. db 구조를 변경하거나 변경할 수 없기 때문에이를 수행 할 수 있습니다. postgresql 문서 에 따라 .

TRUNCATE- 테이블 또는 테이블 세트를 비 웁니다.

TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ]
    [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]

기술

TRUNCATE quickly removes all rows from a set of tables. It has the same effect as an unqualified DELETE on each table, but since it does not actually scan the tables it is faster. Furthermore, it reclaims disk space immediately, rather than requiring a subsequent VACUUM operation. This is most useful on large tables.


Truncate the table othertable, and cascade to any tables that reference othertable via foreign-key constraints:

TRUNCATE othertable CASCADE;

The same, and also reset any associated sequence generators:

TRUNCATE bigtable, fattable RESTART IDENTITY;

Truncate and reset any associated sequence generators:

TRUNCATE revinfo RESTART IDENTITY CASCADE ;

It means that in table kontakty you have a row referencing the row in osoby you want to delete. You have do delete that row first or set a cascade delete on the relation between tables.

Powodzenia!

참조 URL : https://stackoverflow.com/questions/14182079/delete-rows-with-foreign-key-in-postgresql

반응형