如何在SQL Server中为图节点CustomerNode与Customer表设置引用完整性?
问题解答
SQL Server 目前不支持直接在普通关系表和图节点表之间创建原生的外键约束,这也是你在官方文档和SSMS里找不到对应选项的原因——图节点的设计体系和传统关系表相互独立,原生引用完整性规则并不覆盖这种跨类型的关联场景。
不过你可以通过以下两种方案实现需求:
方案一:使用触发器强制约束逻辑
在Customer表上创建一个INSTEAD OF DELETE触发器,在删除Customer记录前检查是否存在对应的CustomerNode,如果存在则阻止删除操作:
CREATE TRIGGER trg_PreventCustomerDeleteBeforeNode ON Customer INSTEAD OF DELETE AS BEGIN SET NOCOUNT ON; -- 检查待删除的Customer是否仍有关联的CustomerNode IF EXISTS ( SELECT 1 FROM deleted d INNER JOIN CustomerNode cn ON d.CustomerId = cn.CustomerId ) BEGIN RAISERROR('请先删除对应的CustomerNode记录,再删除Customer', 16, 1); ROLLBACK TRANSACTION; RETURN; END -- 无关联节点时执行删除 DELETE FROM Customer WHERE CustomerId IN (SELECT CustomerId FROM deleted); END
方案二:用存储过程封装删除操作
封装删除Customer的逻辑到存储过程中,只允许通过存储过程执行删除,在过程里先校验关联节点是否存在:
CREATE PROCEDURE sp_DeleteCustomer @CustomerId INT AS BEGIN SET NOCOUNT ON; -- 校验是否存在关联的CustomerNode IF EXISTS (SELECT 1 FROM CustomerNode WHERE CustomerId = @CustomerId) BEGIN RAISERROR('请先删除对应的CustomerNode记录', 16, 1); RETURN; END -- 执行删除 DELETE FROM Customer WHERE CustomerId = @CustomerId; END
之后可以通过权限控制,禁止用户直接对Customer表执行DELETE操作,只能调用该存储过程完成删除。
内容的提问来源于stack exchange,提问作者wonderful world
相关产品推荐
相关产品推荐

