我尝试在子表上使用外键,并在从父表中删除行时收到错误。这是我对Cascade删除的理解。 使用级联删除
具有级联删除功能的外键意味着如果父级中的记录 表被删除,那么子表中对应的记录 会自动删除。这称为级联删除 SQLite。
具有级联删除功能的外键只能在 CREATE 中定义 TABLE 语句。
提示:您不能使用级联删除将外键添加到表中 ALTER TABLE 因为 SQLite 不支持 ADD CONSTRAINT ALTER TABLE 语句。不过,我们稍后会向您展示解决方法 本教程将允许您使用级联添加外键 删除到现有表。
这是我的父表的 DDL。
CREATE TABLE Astro_Target_Imaged (
ATI_TargetName TEXT NOT NULL,
ATI_Telescope TEXT NOT NULL,
ATI_FocalLength TEXT NOT NULL,
ATI_SITELONG TEXT NOT NULL,
ATI_SITELAT TEXT NOT NULL,
ATI_ICAMERA TEXT,
ATI_ROTNAME TEXT,
ATI_ROTATOR TEXT,
ATI_FWHEEL TEXT,
ATI_FOCNAME TEXT,
ATI_GCAMERA TEXT,
ATI_GSCOPE,
ATI_Location_Name TEXT,
ATI_DataFolder_Location TEXT,
ATI_Posted_FinalProcessed_URL TEXT,
ATI_Bortle TEXT (1),
ATI_Archived TEXT (1) DEFAULT N,
ATI_ArchiveFolderLocation TEXT,
ATI_DateAdded TEXT,
ATI_DateLastUpdated TEXT,
PRIMARY KEY (
ATI_TargetName,
ATI_Telescope,
ATI_FocalLength,
ATI_SITELONG,
ATI_SITELAT
)
);
这是我应用级联和外键的子表。
CREATE TABLE Astro_Target_Imaged_Date (
ATI_TargetName TEXT NOT NULL
REFERENCES Astro_Target_Imaged (ATI_TargetName) ON DELETE CASCADE,
ATI_Telescope TEXT NOT NULL
REFERENCES Astro_Target_Imaged (ATI_Telescope) ON DELETE CASCADE,
ATI_FocalLength TEXT NOT NULL
REFERENCES Astro_Target_Imaged (ATI_FocalLength) ON DELETE CASCADE,
ATID_CCYYMMDD TEXT NOT NULL,
ATI_SITELONG TEXT NOT NULL
REFERENCES Astro_Target_Imaged (ATI_SITELONG) ON DELETE CASCADE,
ATI_SITELAT TEXT REFERENCES Astro_Target_Imaged (ATI_SITELAT) ON DELETE CASCADE,
TZ_UTC_Offset INTEGER (2),
MI_Illumination_Percent TEXT,
PRIMARY KEY (
ATI_TargetName,
ATI_Telescope,
ATI_FocalLength,
ATID_CCYYMMDD,
ATI_SITELONG,
ATI_SITELAT
)
);
错误信息:
[10:45:08] 从表 Astro_Target_Imaged 中删除行时出错: 外键不匹配 - “Astro_Target_Imaged_Date”引用 “Astro_Target_Imaged”
我没有看到名字不匹配,但我可能正在看过去。
根据评论,是的,如果应用,应该可以解决问题。
即外键中指定的父级必须能够引用唯一行(如果存在),而不是潜在的多行。
因此,每个 FKEY 定义必须存在一个 UNQIUE 索引(如果是主键则隐式存在)或通过 UNIQUE 索引显式存在。
在您的情况下,需要 5 个这样的索引,但它们都不存在。然而,您可能想反映父母的独特性。那就是有一个复合的外键定义。
复合外键定义不能在列级别定义,因此必须在表级别定义为约束,语法为:-
https://www.sqlite.org/syntax/table-constraint.html
看来您想要:-
CREATE TABLE IF NOT EXISTS Astro_Target_Imaged_Date (
ATI_TargetName TEXT NOT NULL
-- REFERENCES Astro_Target_Imaged (ATI_TargetName) ON DELETE CASCADE
,
ATI_Telescope TEXT NOT NULL
-- REFERENCES Astro_Target_Imaged (ATI_Telescope) ON DELETE CASCADE
,
ATI_FocalLength TEXT NOT NULL
-- REFERENCES Astro_Target_Imaged (ATI_FocalLength) ON DELETE CASCADE
,
ATID_CCYYMMDD TEXT NOT NULL,
ATI_SITELONG TEXT NOT NULL
-- REFERENCES Astro_Target_Imaged (ATI_SITELONG) ON DELETE CASCADE
,
ATI_SITELAT TEXT -- REFERENCES Astro_Target_Imaged (ATI_SITELAT) ON DELETE CASCADE
,
TZ_UTC_Offset INTEGER (2),
MI_Illumination_Percent TEXT,
PRIMARY KEY (
ATI_TargetName,
ATI_Telescope,
ATI_FocalLength,
ATID_CCYYMMDD,
ATI_SITELONG,
ATI_SITELAT
),
FOREIGN KEY (ATI_TargetName,ATI_Telescope,ATI_FocalLength,ATI_SITELONG,ATI_SITELAT)
REFERENCES Astro_Target_Imaged (ATI_TargetName,ATI_Telescope,ATI_FocalLength,ATI_SITELONG,ATI_SITELAT)
ON DELETE CASCADE ON UPDATE CASCADE
);
使用您的代码,按上述修改,然后:-
INSERT INTO Astro_Target_Imaged
VALUES ('T1','TEL1','F1','SLON1','SLAT200','CAM1','RNAME1','ROR1','W1','FNAME1','GCAM1','GSCOPE1','LOC1','DLOC1','URL1','BORTLE1','ARCY','ARCF1','2024-01-01','2024-01-01')
,('T2','TEL1','F1','SLON1','SLAT200','CAM1','RNAME1','ROR1','W1','FNAME1','GCAM1','GSCOPE1','LOC1','DLOC1','URL1','BORTLE1','ARCY','ARCF1','2024-01-01','2024-01-01')
,('T3','TEL1','F1','SLON1','SLAT200','CAM1','RNAME1','ROR1','W1','FNAME1','GCAM1','GSCOPE1','LOC1','DLOC1','URL1','BORTLE1','ARCY','ARCF1','2024-01-01','2024-01-01')
,('T4','TEL1','F1','SLON1','SLAT200','CAM1','RNAME1','ROR1','W1','FNAME1','GCAM1','GSCOPE1','LOC1','DLOC1','URL1','BORTLE1','ARCY','ARCF1','2024-01-01','2024-01-01')
,('T5','TEL2','F1','SLON1','SLAT200','CAM1','RNAME1','ROR1','W1','FNAME1','GCAM1','GSCOPE1','LOC1','DLOC1','URL1','BORTLE1','ARCY','ARCF1','2024-01-01','2024-01-01')
,('T6','TEL2','F1','SLON1','SLAT200','CAM1','RNAME1','ROR1','W1','FNAME1','GCAM1','GSCOPE1','LOC1','DLOC1','URL1','BORTLE1','ARCY','ARCF1','2024-01-01','2024-01-01')
,('T7','TEL2','F1','SLON1','SLAT200','CAM1','RNAME1','ROR1','W1','FNAME1','GCAM1','GSCOPE1','LOC1','DLOC1','URL1','BORTLE1','ARCY','ARCF1','2024-01-01','2024-01-01')
;
INSERT OR IGNORE INTO Astro_Target_Imaged_Date
VALUES ('T1','TEL1','F1','2024-01-01','SLON1','SLAT200',10,50)
,('T1','TEL1','F1','2024-01-02','SLON1','SLAT200',10,50)
,('T1','TEL1','F1','2024-01-03','SLON1','SLAT200',10,50)
,('T2','TEL1','F1','2024-01-03','SLON1','SLAT200',10,50)
,('T2','TEL1','F1','2024-01-04','SLON1','SLAT200',10,50)
,('T3','TEL1','F1','2024-01-01','SLON1','SLAT200',10,50)
,('T3','TEL1','F1','2024-01-02','SLON1','SLAT200',10,50)
,('T3','TEL1','F1','2024-01-03','SLON1','SLAT200',10,50)
,('T5','TEL2','F1','2024-01-01','SLON1','SLAT200',10,50)
,('T5','TEL2','F1','2024-01-02','SLON1','SLAT200',10,50)
;
;
SELECT a.ati_targetname, a.ati_telescope,b.atid_ccyymmdd,* FROM astro_target_imaged AS a JOIN astro_target_imaged_date AS b
ON a.ati_targetname = b.ati_targetname
AND a.ati_telescope = b.ati_telescope
AND a.ati_focallength = b.ati_focallength
AND a.ati_sitelong = b.ati_sitelong
AND a.ati_sitelat = b.ati_sitelat
;
DELETE FROM astro_target_imaged WHERE ati_targetname = 'T1';
SELECT a.ati_targetname, a.ati_telescope,b.atid_ccyymmdd,* FROM astro_target_imaged AS a JOIN astro_target_imaged_date AS b
ON a.ati_targetname = b.ati_targetname
AND a.ati_telescope = b.ati_telescope
AND a.ati_focallength = b.ati_focallength
AND a.ati_sitelong = b.ati_sitelong
AND a.ati_sitelat = b.ati_sitelat
;
SELECT * FROM astro_target_imaged_date;
UPDATE astro_target_imaged SET ati_targetname = 'UPDATED'||ati_targetname WHERE ati_targetname LIKE '%5';
SELECT a.ati_targetname, a.ati_telescope,b.atid_ccyymmdd,* FROM astro_target_imaged AS a JOIN astro_target_imaged_date AS b
ON a.ati_targetname = b.ati_targetname
AND a.ati_telescope = b.ati_telescope
AND a.ati_focallength = b.ati_focallength
AND a.ati_sitelong = b.ati_sitelong
AND a.ati_sitelat = b.ati_sitelat
;
SELECT * FROM astro_target_imaged_date;
SELECT a.ati_targetname, a.ati_telescope,b.atid_ccyymmdd,* ....
结果是:-
原来的SELECT:-
从父级删除 T1 后的
SELECT
:-
...._date 表(即级联删除的结果):-
单个T5父级更新后的SELECT:-
和 ...._日期表:-