سؤال
وأنا خلقت أساسا بعض الجداول للعب مع حولها: لدي جدولين الرئيسية، وكثير، كثير انضمام الجدول. هنا هو 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
)
إذا كنت تريد فقط حذف JOB
s اليتيم مرتبطة سابقا 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
)
وأنت لا تستطيع حذف الصفوف التي ترتبط من قبل الأجانب على الجدول الآخر ...