问题描述:
某个基础信息表,与系统中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
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))
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/8591181/viewspace-891978/ ,如需转载,请注明出处,否则将追究法律责任。