1

想象一下我有以下结构:

DECLARE @Products TABLE (
    MemberId INT,
    ProductId INT,
    GlobalProductId INT,
    PRIMARY KEY (MemberId, ProductId));
INSERT INTO @Products VALUES (1, 1, NULL);--this is my "global product"
INSERT INTO @Products VALUES (2, 1, NULL);--this is okay
INSERT INTO @Products VALUES (2, 2, 1);--this is okay
INSERT INTO @Products VALUES (2, 3, 2);--this should fail
SELECT * FROM @Products;

我要强制执行的规则是 MemberId = 1 持有全球产品,所有其他 MemberId 持有普通产品。一组普通产品可以链接到单个全局产品。

所以我希望会员的产品能够链接到全局产品,即会有一个外键约束,如果 GlobalProductId 不是 NULL,那么应该存在一个与 GlobalProductId 匹配的 ProductId,其中 MemberId = 1。

在上面的示例中,我有一个 ProductId = 1 的全局产品。然后我创建了三个普通产品:

  • 第一个没有全球产品;
  • 第二个链接到我之前创建的单个全球产品(然后我可以将更多产品链接到同一个全球产品);
  • 第三个应该失败,因为我已将其链接到不存在的全球产品,即此脚本将不返回任何内容:

    SELECT * FROM @Products WHERE MemberId = 1 AND ProductId = 2;
    

我可以看到最简单的解决方案是创建一个新表来保存全球产品。这种方法的问题是我有一整套例程来加载、更新、删除 Product 表中的数据,还有第二组例程来执行计算等。如果我要引入一个新的“全球产品”表,那么我将不得不复制几十个 UDF 来实现这一点,我的代码会变得更加复杂。

4

2 回答 2

2

添加一个固定为的计算列,1然后添加一个外键:

CREATE TABLE Products (
    MemberId INT,
    ProductId INT,
    GlobalProductId INT,
    PRIMARY KEY (MemberId, ProductId),
    GlobalMemberId AS 1 PERSISTED,
    FOREIGN KEY (GlobalMemberId,GlobalProductID)
        references Products (MemberId,ProductID)
    );
INSERT INTO Products VALUES (1, 1, NULL);--this is my "global product"
INSERT INTO Products VALUES (2, 1, NULL);--this is okay
INSERT INTO Products VALUES (2, 2, 1);--this is okay
INSERT INTO Products VALUES (2, 3, 2);--this should fail
SELECT * FROM Products;

这会产生以下结果:

消息 547,第 16 级,状态 0,第 1 行

INSERT 语句与 FOREIGN KEY SAME TABLE 约束“ FK__Products__7775B2CE”冲突。abc数据库“ ”、表“ ”中发生冲突dbo.Products

该语句已终止。

MemberId    ProductId   GlobalProductId GlobalMemberId
----------- ----------- --------------- --------------
1           1           NULL            1
2           1           NULL            1
2           2           1               1
于 2013-05-23T14:15:21.140 回答
0

为什么不只是添加一个CHECK约束:

ALTER TABLE Products ADD CONSTRAINT CHK_ColumnD_GlobalProductId 
CHECK (GlobalProductId IS NULL AND MemberId = 1 
       OR GlobalProductId IS NOT NULL AND MemberId != 1);

和一个FOREIGN KEY

ALTER TABLE Products ADD CONSTRAINT fk_SelfProducts
FOREIGN KEY (GlobalProductId )
REFERENCES Products (ProductId)
于 2014-09-10T10:09:56.807 回答