不同数据库中两个表之间的引用完整性的存储过程?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不同数据库中两个表之间的引用完整性的存储过程?相关的知识,希望对你有一定的参考价值。
对于两个表A和B,我想实现参照完整性,以便在表A中,外键的值必须存在于表B中,而在表B中,只有在该值不存在的情况下才能删除或修改主键。表A.我的要求是我希望将表A和B作为变量,并将该过程应用于表的任意实例。那是,
sp_referential_integrity_across_databases(A, B)
我已经弄清楚如何将引用完整性作为一对特定表的触发器。我想知道编写这样的存储过程是否可行以节省未来的工作量?
我的环境是Microsoft SQL Server 2017.解决方案越便携越好。
这是我精心设计的程序:
表“A”上的触发器用于插入和更新:
USE DWPractice
IF OBJECT_ID ('dbo.trgCheckCustomer_Cat_Id_Customer_D', 'TR') IS NOT NULL
DROP Trigger trgCheckCustomer_Cat_Id_Customer_D;
GO
CREATE TRIGGER trgCheckCustomer_Cat_Id_Customer_D
ON Customer_D
AFTER INSERT, UPDATE
AS
IF NOT EXISTS
(
SELECT Customer_Cat_Id
FROM inserted
WHERE Customer_Cat_Id IN (SELECT Customer_Cat_Id FROM [OtherDW].[dbo].[Customer_Cat_D])
)
BEGIN
RAISERROR('Lookup Value Not Found -- Inerst Failed', 16, 1);
ROLLBACK TRANSACTION;
END;
表“B”上的触发器用于删除和更新:
USE OtherDW
IF OBJECT_ID ('dbo.trgCheckCustomer_Cat_Id_Customer_Cat_D', 'TR') IS NOT NULL
DROP Trigger trgCheckCustomer_Cat_Id_Customer_Cat_D;
GO
CREATE TRIGGER trgCheckCustomer_Cat_Id_Customer_Cat_D
ON Customer_Cat_D
AFTER DELETE, UPDATE
AS
Begin
IF EXISTS
(
SELECT Customer_Cat_Id
FROM deleted
WHERE Customer_Cat_Id IN (SELECT Customer_Cat_Id FROM [DWPractice].[dbo].[Customer_D])
)
BEGIN
RAISERROR('Lookup Value Found -- Delete Failed', 16, 1);
ROLLBACK TRANSACTION;
END;
-- It seems that the following for the case of update is not needed
-- The above clauses would get executed even for the case of update.
-- IF EXISTS
-- (
-- SELECT Customer_Cat_Id
-- FROM inserted
-- WHERE Customer_Cat_Id IN (SELECT Customer_Cat_Id FROM [DWPractice].[dbo].[Customer_D])
-- )
-- BEGIN
-- RAISERROR('Lookup Value Found -- Update Failed', 16, 1);
-- ROLLBACK TRANSACTION;
-- END;
End;
如果存储过程不是最佳实践,那么最佳实践是什么?在我看来,有很多样板代码,只有数据库名称和表名是变量。
答案
(第一个)触发器中的逻辑不正确。如果你在inserted
中有多行,那么只有一行必须匹配。相反,你想要:
CREATE TRIGGER trgCheckCustomer_Cat_Id_Customer_D ON Customer_D AFTER INSERT, UPDATE
AS BEGIN
IF EXISTS (SELECT 1
FROM inserted i LEFT JOIN
[OtherDW].[dbo].[Customer_Cat_D] d
ON i.Customer_Cat_Id = d.Customer_Cat_Id
WHERE d.Customer_Cat_Id IS NULL
)
BEGIN
RAISERROR('Lookup Value Not Found -- Insert Failed', 16, 1);
ROLLBACK TRANSACTION;
END;
END; -- trigger
以上是关于不同数据库中两个表之间的引用完整性的存储过程?的主要内容,如果未能解决你的问题,请参考以下文章