سؤال

وأنا خلقت أساسا بعض الجداول للعب مع حولها: لدي جدولين الرئيسية، وكثير، كثير انضمام الجدول. هنا هو DDL: (أنا أستخدم 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);

وأريد إنشاء بيان حذف يحذف الأيتام من JOB (في حال وجود إدخال واحد فقط في الجدول الانضمام لوظيفة محددة) على أساس PERSON.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

وأين X هو بعض person_id. لقد حاولت الكثير من الطرق المختلفة. وأعتقد أنه هو "COUNT" الجزء الذي يسبب المشاكل. أنا الصاعد SQL، لذلك فإن أي مساعدة سيكون محل تقدير كبير.

هل كانت مفيدة؟

المحلول

وأنا لا التالية.

وأنت لا تستطيع حذف صفوف JOB التي JOB_PERSON الصفوف (حتى واحد) بسبب contraints FK الخاص بك. وبالتالي ليس هناك طريقة لحذف صفوف JOB على أساس صفوف PERSON.

وإلى أن يتم حذف

والصفوف JOB_PERSON قبل أن يتم حذف إما JOB أو PERSON.

إذا كنت ترغب في حذف كافة الصفوف JOB مع عدم وجود JOB_PERSON، ثم طريقة واحدة هي:

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
)

إذا كنت تريد فقط حذف JOBs اليتيم مرتبطة سابقا 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
)

نصائح أخرى

وهذا سوف تحذف من إدخالات JOB الجدول التي ليس لها إدخال في جدول JOB_PERSON (Orpheans).

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

وأنت لا تستطيع حذف الصفوف التي ترتبط من قبل الأجانب على الجدول الآخر ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top