현상
Self FK(Foreign Key) 참조되어있는 Table PK(Primary Key) Drop 시 PK정보만 삭제되어 버리는 현상이 발생하였습니다.
재현 시나리오
create table test ( no number , yy varchar(4), mm varchar(4), par_no number);
create unique index pk_test on test (no);
alter table test add constraint pk_test primary key (no) using index pk_test;
alter table test add constraint fk_self_test
foreign key (par_no) references test (no);
alter table test drop primary key; → 해당 PK는 FK가 바라보고 있어 삭제 불가능해야 맞지만 삭제됨
select * from dba_constraints where table_name='TEST'; → FK도 지워진 것 처럼 보이는 현상 발생( 시스템 정보에는 FK 정보가 남아있음)
0 row selected.
insert into test values (1,2021,1,1);
TBR-12035: Internal error -528005 occurred.
SQL
복사
원인
PK(기본키)를 참조하는 FK(외래키)가 있을 경우, FK를 삭제한 후 PK를 Drop 해야 합니다. 그러나 PK만 Drop되면서 시스템 내부 딕셔너리 정보에 FK정보가 남아 있어 에러가 발생하였습니다.
해결
패치를 적용하여 해결합니다. (적용 패치: 241435a)
•
241435a 패치: self references constraint (자기 참조 제약조건) 일 때 references constraint이 바라보는 primary key가 drop 되지 않도록 수정 적용한 패치입니다.
주의
티맥스티베로에서 제공하는 기술지원을 통해 패치를 적용합니다.
참고
이미 문제가 된 테이블의 FK 정보 삭제 방법은 다음과 같습니다.
SYS 계정 수행 ( 전체 User 대상 문제되는 FK Drop)
SET SERVEROUTPUT ON;
DECLARE
CURSOR csr IS
SELECT c.username, a.obj_id, a.name
FROM _dd_con a, _dd_obj b, dba_users c
WHERE a.obj_id = b.obj_id
AND b.owner_id = c.user_id
AND a.ref_obj_id = a.obj_id
AND a.ref_con_id NOT IN (SELECT con_id FROM _dd_con);
tbl_obj_id NUMBER;
con_name VARCHAR2(1000);
tbl_name VARCHAR2(1000);
username VARCHAR2(100);
drop_ref_con_ddl VARCHAR2(1000);
BEGIN
OPEN csr;
LOOP
FETCH csr INTO username, tbl_obj_id, con_name;
EXIT WHEN csr%NOTFOUND;
SELECT name INTO tbl_name
FROM sys._dd_obj
WHERE obj_id = tbl_obj_id;
DBMS_OUTPUT.PUT_LINE('USERNAME : ' || username ||
' TABLE : ' || tbl_name ||
' OBJ_ID : ' || tbl_obj_id ||
' SELF_REF_CONSTRAINT : ' || con_name ||
' IS INCONSISTENT');
drop_ref_con_ddl := 'ALTER TABLE ' || username || '.' || tbl_name ||
' DROP CONSTRAINT ' || con_name;
EXECUTE IMMEDIATE drop_ref_con_ddl;
DBMS_OUTPUT.PUT_LINE('USERNAME : ' || username ||
' TABLE : ' || tbl_name ||
' OBJ_ID : ' || tbl_obj_id ||
' SELF_REF_CONSTRAINT : ' || con_name ||
' DROPPED');
END LOOP;
CLOSE csr;
END;
/
SQL
복사