实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
2008-01-03 14:34
459 查看
问题描述:某个基础信息表,与系统中30多个表存在外键关系,当删除基础数据时,需要判断是否已经被用过,如果用过则更改标志位,如果没有用过则直接删除,如何能很好实现这个处理?最好能够自动适应表的变化 问题解决(SQL Server 2005)-- SQL Server 2005的错误处理容易控制, 因此, SQL Server 2005中可以直接删除, 通过错误处理来确定是否需要更新. -- 示例如下.USE tempdbGO CREATE TABLE m( id int PRIMARY KEY, bz bit)INSERT m SELECT 1, 0UNION 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, 1GO -- 删除处理存储过程CREATE PROC dbo.p_delete @id intASSET NOCOUNT ONBEGIN TRYBEGIN TRAN DELETE FROM m WHERE id = @idCOMMIT TRANEND TRYBEGIN 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 CATCHGO -- 调用EXEC dbo.p_delete 1EXEC dbo.p_delete 2SELECT * FROM mSELECT * FROM cGO DROP TABLE c, mDROP PROC dbo.p_delete 问题解决(SQL Server 2000)-- SQL Server 2000 对错误处理不好控制, 一般还是建议做判断-- 通过系统表查询系统表,可以获取某个表关联的所有外键表 -- 示例存储过程CREATE PROC dbo.p_Delete @tbname sysname, -- 基础数据表名 @PkFieldName sysname, -- 基础数据表关键字段名 @PkValue int -- 要删除的基础数据表关键字值ASSET NOCOUNT ONDECLARE @bz bit, @s nvarchar(4000)DECLARE tb CURSOR LOCALFORSELECT 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.idWHERE A.xtype = 'f' AND C.xtype = 'U' AND OBJECT_NAME(B.rkeyid) = @tbnameOPEN tbFETCH tb INTO @sWHILE @@FETCH_STATUS = 0BEGIN 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 @sENDCLOSE tbDEALLOCATE tb SET @s = N'DELETE FROM ' + QUOTENAME(@tbname) + N' WHERE ' + QUOTENAME(@PkFieldName) + N' = @id'EXEC sp_executesql @s, N'@id int', @PkValueGO 注意事项设置表的主/外键关系的时候,不要设置级联删除(ON DELETE CASCADE)
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1236639
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1236639
相关文章推荐
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- [导入]实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 转:邹建--实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除 (转)
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据引用, 有标志, 无则删除
- 实现删除主表数据时, 判断与之关联的外键表是否有数据
- 删除时判断外键关联的是否有记录
- 主外键表关联数据的同时删除