Pergunta

Eu basicamente criado algumas tabelas para brincar com: Eu tenho duas tabelas principais, e uma Muitos-muitos tabela. Aqui está o DDL: (estou usando HSQLDB)

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);

Eu quero criar uma instrução de exclusão, que elimina os órfãos de JOB (se existe apenas uma entrada na tabela para um trabalho específico juntar-se) com base na PERSON.PERSON_ID.

Em linguagem pseudo:

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

Onde X é algum person_id. Eu tentei um monte de maneiras diferentes; Eu acho que é a parte "COUNT" que está causando problemas. Eu sou um novato SQL, portanto, qualquer ajuda seria muito apreciada.

Foi útil?

Solução

Eu não estou entendendo.

Você não pode linhas JOB de exclusão que têm linhas JOB_PERSON (mesmo um) por causa de suas contraints FK. Assim, não há maneira de linhas JOB de exclusão baseadas em linhas PERSON.

linhas JOB_PERSON têm de ser eliminados antes que qualquer um JOB ou PERSON pode ser excluída.

Se você quiser excluir todas as linhas JOB sem JOB_PERSON, em seguida, uma maneira é:

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

Se você quiser excluir todas as linhas JOB_PERSON para uma pessoa em particular e, em seguida, todos os órfãos, fazê-lo em duas etapas:

DELETE FROM JOB_PERSON
WHERE PERSON_ID = X

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

Se você quiser excluir somente os JOBs órfãos anteriormente ligados ao X, você vai precisar para manter aqueles em uma tabela temporária antes da primeira eliminação.

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
)

Outras dicas

Isto irá excluir de suas entradas JOB da tabela que não têm entrada no JOB_PERSON mesa (Orpheans).

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

Você pode linhas não de exclusão que são ligados por uma estrangeira em uma outra mesa ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top