分享
 
 
 

实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

问题描述:

某个基础信息表,与系统中30多个表存在外键关系,当删除基础数据时,需要判断是否已经被用过,如果用过则更改标志位,如果没有用过则直接删除,如何能很好实现这个处理?最好能够自动适应表的变化

问题解决(SQL Server 2005)

-- SQL Server 2005的错误处理容易控制, 因此,SQL Server 2005中可以直接删除, 通过错误处理来确定是否需要更新.

-- 示例如下.

USE tempdb

GO

CREATE TABLE m(

id int PRIMARY KEY,

bz bit)

INSERT m SELECT 1, 0

UNION ALL SELECT 2, 0

CREATE TABLE c(

id int primary key,

a_id int references m(id)

ON DELETE NO ACTION)

INSERT c SELECT 1, 1

GO

-- 删除处理存储过程

CREATE PROC dbo.p_delete

@id int

AS

SET NOCOUNT ON

BEGIN TRY

BEGIN TRAN

DELETE FROM m WHERE id = @id

COMMIT TRAN

END TRY

BEGIN CATCH

ROLLBACK TRAN

IF ERROR_NUMBER() = 547 -- 如果是外键约束错误

BEGIN

BEGIN TRY

BEGIN TRAN -- 更新标志

UPDATE m SET bz = 1

WHERE id = @id

COMMIT TRAN

END TRY

BEGIN CATCH

SELECT ERROR_NUMBER(), ERROR_MESSAGE()

END CATCH

END

ELSE

SELECT ERROR_NUMBER(), ERROR_MESSAGE()

END CATCH

GO

-- 调用

EXEC dbo.p_delete 1

EXEC dbo.p_delete 2

SELECT * FROM m

SELECT * FROM c

GO

DROP TABLE c, m

DROP PROC dbo.p_delete

问题解决(SQL Server 2000)

-- SQL Server 2000 对错误处理不好控制, 一般还是建议做判断

-- 通过系统表查询系统表,可以获取某个表关联的所有外键表

-- 示例存储过程

CREATE PROC dbo.p_Delete

@tbname sysname, -- 基础数据表名

@PkFieldName sysname, -- 基础数据表关键字段名

@PkValue int -- 要删除的基础数据表关键字值

AS

SET NOCOUNT ON

DECLARE @bz bit, @s nvarchar(4000)

DECLARE tb CURSOR LOCAL

FOR

SELECT N'

SET @bz = CASE WHEN EXISTS(

SELECT * FROM ' + QUOTENAME(@tbname)

+ N' A, ' + QUOTENAME(OBJECT_NAME(B.fkeyid))

+ N' B

WHERE A.' + QUOTENAME((SELECT name FROM syscolumns WHERE colid = B.rkey AND id = B.rkeyid))

+ N' = B.' + QUOTENAME((SELECT name FROM syscolumns WHERE colid = B.fkey AND id = B.fkeyid))

+ N' AND A.' + QUOTENAME((SELECT name FROM syscolumns WHERE colid = B.rkey AND id = B.rkeyid))

+ N' = @id) THEN 1 ELSE 0 END'

FROM sysobjects A

JOIN sysforeignkeys B

ON A.id= B.constid

JOIN sysobjects C

ON A.parent_obj = C.id

WHERE A.xtype = 'f'

AND C.xtype = 'U'

AND OBJECT_NAME(B.rkeyid) = @tbname

OPEN tb

FETCH tb INTO @s

WHILE @@FETCH_STATUS = 0

BEGIN

EXEC sp_executesql @s, N'@tbname sysname, @id int, @bz bit OUT', @tbname, @PkValue, @bz OUT

IF @bz = 1

BEGIN

SET @s = N'UPDATE ' + QUOTENAME(@tbname)

+ N' SET bz = 1 WHERE ' + QUOTENAME(@PkFieldName)

+ N' = @id'

EXEC sp_executesql @s, N'@id int', @PkValue

RETURN

END

FETCH tb INTO @s

END

CLOSE tb

DEALLOCATE tb

SET @s = N'DELETE FROM ' + QUOTENAME(@tbname)

+ N' WHERE ' + QUOTENAME(@PkFieldName)

+ N' = @id'

EXEC sp_executesql @s, N'@id int', @PkValue

GO

注意事项

设置表的主/外键关系的时候,不要设置级联删除(ON DELETE CASCADE)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有