开发者社区> 问答> 正文

我们如何创建一个表约束,将一列限制为x个相同值?

在我们的零售系统中,我们计划将购物篮信息从浏览器Cookie移到表格中。我们目前在C#应用程序中实现了篮子的限制,但是如果可能的话,我们希望将业务逻辑作为约束向下移动到数据库中。

CREATE TABLE [dbo].[BasketProduct](
    [BasketProductId] [int] IDENTITY(1,1) NOT NULL,
    [BasketId] [int] NOT NULL,
    [ProductId] [int] NOT NULL,
    [Quantity] [int] NOT NULL,
 CONSTRAINT [PK_BasketProduct] PRIMARY KEY CLUSTERED 
([BasketProductId] ASC))

我们希望限制每个购物篮最多包含10个唯一商品,但每个商品都允许有任意数量,因此,篮子ID值在表格中最多只能显示10次。

似乎没有明显的约束来执行此操作,因为在计算列中不允许包含窗口函数的聚合。

有人可以推荐合适的方法吗?

展开
收起
祖安文状元 2020-01-05 14:06:22 423 0
1 条回答
写回答
取消 提交回答
  • 这并不理想,但是正如我在评论中提到的那样,我将在执行INSERT/ UPDATE/ 的SP中处理此问题DELETE(不太可能需要DELETE)。因此,对于,INSERT您将具有如下所示的内容:

    USE Sandbox; GO

    CREATE TABLE [dbo].[BasketProduct](
        [BasketProductId] [int] IDENTITY(1,1) NOT NULL,
        [BasketId] [int] NOT NULL,
        [ProductId] [int] NOT NULL,
        [Quantity] [int] NOT NULL,
     CONSTRAINT [PK_BasketProduct] PRIMARY KEY CLUSTERED 
    ([BasketProductId] ASC));
    GO
    
    CREATE PROC AddBasketProduct @BasketID int, @ProductID int, @Quantity int AS
    BEGIN
    
        DECLARE @DistinctProducts int;
    
        SELECT @DistinctProducts = COUNT(DISTINCT ProductID)
        FROM dbo.BasketProduct WITH (UPDLOCK) --As we need to control concurrency issues
        WHERE BasketId = @BasketID
          AND ProductID != @ProductID ;
    
        IF @DistinctProducts >= 10
            THROW 71245, N'Cannot have more than 10 different products in a single basket.',16; --Choose an error number and state appropraite for your applciation
        ELSE
            INSERT INTO dbo.BasketProduct (BasketId,
                                           ProductId,
                                           Quantity)
            VALUES(@BasketID,@ProductID,@Quantity);
    END;
    
    GO
    --Make some sample data
    INSERT INTO dbo.BasketProduct (BasketId,
                                   ProductId,
                                   Quantity)
    VALUES(1,1,1),
          (1,2,1),
          (1,3,1),
          (1,4,1),
          (1,5,1),
          (1,6,1),
          (1,7,1),
          (1,8,1),
          (1,9,1),
          (1,10,1); --10 products.
    GO
    --11th product, will fail
    EXEC dbo.AddBasketProduct @BasketID = 1,
                              @ProductID = 11,
                              @Quantity = 1;
    
    GO
    
    --Repetition of product 2, will work
    EXEC dbo.AddBasketProduct @BasketID = 1,
                              @ProductID = 2,
                              @Quantity = 1;
    GO
    
    DROP PROC dbo.AddBasketProduct;
    DROP TABLE dbo.BasketProduct;
    
    2020-01-05 14:06:41
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载