2008-11-07 5 views
1

필자는 기본적으로 두 개의 주 테이블과 Many-Many 조인 테이블을 가지고 놀 수있는 테이블을 만들었습니다. (I는 HSQLDB를 사용하고 있습니다)SQL : Complex Deletion

CREATE TABLE PERSON 
(
    PERSON_ID INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 
    NAME VARCHAR(50), MAIN_PERSON_ID INTEGER 
) 

CREATE TABLE JOB 
(
    JOB_ID INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 
    NAME VARCHAR(50) 
) 
CREATE TABLE JOB_PERSON 
(
    PERSON_ID INTEGER, 
    JOB_ID INTEGER 
) 
ALTER TABLE JOB_PERSON ADD 
    CONSTRAINT FK_PERSON_JOB FOREIGN KEY(PERSON_ID) 
    REFERENCES PERSON ON DELETE CASCADE ON UPDATE CASCADE 

ALTER TABLE JOB_PERSON ADD 
    CONSTRAINT FK_JOB_PERSON FOREIGN KEY(JOB_ID) 
    REFERENCES JOB ON DELETE CASCADE ON UPDATE CASCADE 

ALTER TABLE PERSON ADD 
    CONSTRAINT FK_PERSON_PERSON FOREIGN KEY(MAIN_PERSON_ID) 
    REFERENCES PERSON ON DELETE CASCADE ON UPDATE CASCADE 

insert into person values(null,'Arthur', null); 
insert into person values(null,'James',0); 
insert into job values(null, 'Programmer') 
insert into job values(null, 'Manager') 
insert into job_person values(0,0); 
insert into job_person values(0,1); 
insert into job_person values(1,1); 

내가 (특정 작업에 대한 조인 테이블에 하나의 항목 만이 존재하는 경우) 작업에서 고아를 삭제하는 DELETE 문을 생성 할 사람에 따라 다음은 DDL이다 .PERSON_ID. 의사 언어에서

: X 일부 person_id로입니다

delete from job where job_person.job_id=job.job_id 
AND count(job_person.job_id)=1 AND job_person.person_id=X 

. 나는 많은 다른 방법을 시도했다. 문제를 일으키는 것은 "COUNT"부분이라고 생각합니다. 나는 SQL 신참이다. 그래서 어떤 도움이라도 대단히 감사 할 것이다.

+0

나는 질문에 완전히 명확하지 않다. 작업 테이블의 고아는 job_person 테이블에 해당 항목이 없습니다. 이 JOB JOB_ID NOT IN ( SELECT JOB_ID에서 삭제 : 당신이 다른 테이블에 의해 사용되는 데이터를 삭제하려고하는 이유 – Dave

+0

데이브에 따르면 나는 이것이 내가 찾던 기능입니다 – Fred

+0

... 이해하지 않는다 FROM JOB_PERSON ) – systemoutprintln

답변

2

나는 팔로우하지 않는다.

귀하의 FK 조건 때문에 JOB_PERSON 개의 행 (심지어 하나)이있는 행을 삭제할 수 없습니다. 따라서 PERSON 행을 기준으로 JOB 행을 삭제할 수있는 방법이 없습니다.

JOB_PERSONJOB 또는 PERSON을 삭제하려면 먼저 행을 삭제해야합니다. 당신이 더 JOB_PERSON 모든 JOB 행을 삭제하려면

, 다음 한 가지 방법은 다음과 같습니다

DELETE FROM JOB 
WHERE JOB_ID NOT IN (
    SELECT JOB_ID 
    FROM JOB_PERSON 
) 

특정 사람에 대한 모든 JOB_PERSON 행과 모든 고아를 삭제하려면이 두 단계에서 할 :

DELETE FROM JOB_PERSON 
WHERE PERSON_ID = X 

DELETE FROM JOB 
WHERE JOB_ID NOT IN (
    SELECT JOB_ID 
    FROM JOB_PERSON 
) 

당신이 JOB 이전에 X에 연결 유일의 고아를 삭제하려는 경우 먼저 삭제하기 전에 임시 테이블에있는 사람들을 보유해야합니다.

INSERT INTO TEMP_TABLE 
SELECT JOB.JOB_ID 
FROM JOB 
INNER JOIN JOB_PERSON 
    ON JOB_PERSON.JOB_ID = JOB.JOB_ID 
WHERE JOB_PERSON.PERSON_ID = X 

DELETE FROM PERSON 
WHERE PERSON_ID = X 

-- YOUR CASCADING DELETE DOES THIS: 
/* 
DELETE FROM JOB_PERSON 
WHERE PERSON_ID = X 
*/ 

-- Now clean up (only) new orphans on the other side 
DELETE FROM JOB 
WHERE JOB_ID NOT IN (
    SELECT JOB_ID 
    FROM JOB_PERSON 
) 
AND JOB_ID IN (
    SELECT JOB_ID 
    FROM TEMP_TABLE 
) 
+0

"JOB_PERSON 행을 삭제해야 JOB 또는 PERSON을 삭제할 수 있습니다." - ON DELETE CASCADE가 사용 된 경우가 아닙니다. –

+0

맞아, 그는 고아들을 어떤 식 으로든 떠나게 될거야. 코드를 업데이트하겠습니다. –

1

테이블에서 항목 JOB_PERSON (Orpheans)이없는 항목을 삭제합니다. 당신은 다른 테이블에 외국으로 연결되는 행을 삭제할 수 없습니다

DELETE FROM JOB 
WHERE JOB_ID NOT IN (
    SELECT JOB_ID 
    FROM JOB_PERSON 
) 

...

+0

"NOT IN"이 맞다고 생각하십니까? – systemoutprintln