引用外键并为父表中的列添加检查约束

时间:2019-03-27 13:29:41

标签: sql sql-server

如何向表BusinessCategories中添加相关IsBusinessCategory的列Categories.ID的值为'true'的检查?

CREATE TABLE [dbo].[Categories](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ParentID] [int] NULL,
    [DisplayNameHe] [nvarchar](400) NOT NULL,
    [DisplayNameEn] [nvarchar](400) NOT NULL,
    [DisplayNameEs] [nvarchar](400) NOT NULL,
    [CreateDate] [datetime] NOT NULL,
    [Status] [bit] NOT NULL,
    [IsBusinessCategory] [bit] NULL
)



CREATE TABLE [dbo].[BusinessCategories](
    [ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [BusinessCategoryID] [INT] NOT NULL REFERENCES Categories(ID) -- Need to check that is 
     businessCategory ==1
    [BusinessID] [INT] NOT NULL REFERENCES Business(ID)
)

目标是只能将 IsBusinessCategory == true Categories 表中的值插入 BusinessCategoryID 列。

2 个答案:

答案 0 :(得分:1)

我不建议这种解决方案,应该在应用程序的业务层中完成

在SQL方面,有一个棘手的方法,不是最佳方法,但可行...

首先创建一个标量函数,该函数返回所选类别的isBusinessCategory值

CREATE FUNCTION fn_isBusinessCategory (@CatID INT) RETURNS INT
AS
BEGIN
    RETURN (SELECT isBusinessCategory FROM Categories WHERE CategoryID = @CatID)
END
GO

创建另一个标量函数,如果在BusinessCategories中引用了给定类别,则该函数返回1。

CREATE FUNCTION fn_isBusinessCategoryValid (@CatID INT, @isBusinessCat BIT) RETURNS BIT
AS
BEGIN
    IF @isBusinessCat = 1
        RETURN 1
    ELSE IF EXISTS (SELECT 1 FROM BusinessCategories WHERE CategoryID = @CatID)
        RETURN 0
    ELSE
        RETURN 1
END
GO

添加以下约束

第1步外键可验证两个表之间的完整性

ALTER TABLE BusinessCategories ADD CONSTRAINT FK_BusinessCategory 
FOREIGN KEY (CategoryID) 
REFERENCES Categories (CategoryID)

步骤2检查约束条件以验证类别is_businessCategory

ALTER TABLE BusinessCategories ADD CONSTRAINT ck_BusinessCategory 
CHECK (dbo.fn_isBusinessCategory(CategoryID) = 1)

第3步检查约束,以防止使用时将类别更改为非businessCategory

ALTER TABLE Categories ADD CONSTRAINT ck_Category_isBusinessCategory 
CHECK (dbo.fn_isBusinessCategoryValid(CategoryID, isBusinessCategory) = 1)

答案 1 :(得分:0)

  

目标是只能插入到BusinessCategoryID列   类别表中具有IsBusinessCategory == true的值。

您可以通过编写一个以static作为参数的UDF并查询Categories表以获取BusinessCategoryID的值来做很多事情。 CHECK约束将仅测试参数的返回值是true还是false。

但是请注意,仅当您向IsBusinessCategory表中添加行时,才会检查此约束。如果有人更改了BusinessCategories表中IsBusinessCategory的值,则CHECK约束将无法捕获它。您需要在Categories表上放置一个单独的约束来捕获该约束。