我需要一个表格表格来保存像这样的层次结构树数据(即大陆,国家,城市)
id name parent
-------------------
1 world null
2 Europe 1
3 Asia 1
4 France 2
5 Paris 4
6 Lyon 4
Run Code Online (Sandbox Code Playgroud)
我要删除France
,希望该表可以级联删除所有法国城市。但是当我像这样创建表时
create table locations
(
id int identity(1, 1),
name varchar(255) not null,
parent_id int,
constraint pk__locations
primary key clustered (id),
constraint fk__locations
foreign key (parent_id)
references locations (id)
on delete cascade
on update no action
)
Run Code Online (Sandbox Code Playgroud)
我有一个错误
在表“位置”上引入外键约束“ fk__locations”可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。
信息说
ON DELETE NO ACTION
-这正是我想要的ON UPDATE NO ACTION
-指定有人可以帮忙吗?
这不可能。你可以用INSTEAD OF TRIGGER
create table locations
(
id int identity(1, 1),
name varchar(255) not null,
parent_id int,
constraint pk__locations
primary key clustered (id)
)
GO
INSERT INTO locations(name,parent_id) VALUES
('world',null)
,('Europe',1)
,('Asia',1)
,('France',2)
,('Paris',4)
,('Lyon',4);
GO
Run Code Online (Sandbox Code Playgroud)
-- 此触发器将使用递归 CTE 来获取您要删除的所有 ID 之后的所有 ID。这些 ID 被删除。
CREATE TRIGGER dbo.DeleteCascadeLocations ON locations
INSTEAD OF DELETE
AS
BEGIN
WITH recCTE AS
(
SELECT id,parent_id
FROM deleted
UNION ALL
SELECT nxt.id,nxt.parent_id
FROM recCTE AS prv
INNER JOIN locations AS nxt ON nxt.parent_id=prv.id
)
DELETE FROM locations WHERE id IN(SELECT id FROM recCTE);
END
GO
Run Code Online (Sandbox Code Playgroud)
--在这里测试,尝试不同的ID。你也可以试试WHERE id IN(4,3)
...
SELECT * FROM locations;
DELETE FROM locations WHERE id=4;
SELECT * FROM locations
GO
Run Code Online (Sandbox Code Playgroud)
--清理(小心真实数据!)
if exists(select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME='locations')
---DROP TABLE locations;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
741 次 |
最近记录: |