简体   繁体   中英

Reference a foreign key and Add check constraint for column in parent table

How can I Add to the Table BusinessCategories a check that the column IsBusinessCategory value is 'true' for the related Categories.ID ?

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)
)

The goal is to be able to insert to the column BusinessCategoryID only values from Categories table that has IsBusinessCategory == true .

I don't recommend that kind of solution, that should be done in the application's business layer

In SQL side there is a tricky way, not optimal, but doable...

First create an scalar function that returns the isBusinessCategory value of the selected category

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

Create another scalar function that returns 1 if a given category is referenced in BusinessCategories

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

Add the following constraints

Step 1 Foreign key to validate integrity between two tables

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

Step 2 Check constraint to validate that category is_businessCategory

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

Step 3 Check constraint to prevent a category to be changed as non businessCategory when is used

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

The goal is to be able to insert to the column BusinessCategoryID only values from Categories table that has IsBusinessCategory == true.

You can do this much by writing a UDF that takes BusinessCategoryID as a parameter and queries the Categories table to get the value of IsBusinessCategory . The CHECK constraint would simply test whether the returned value of the parameter is true or false.

Be warned however, that this constraint will only be checked when you add rows to the BusinessCategories table. If someone changes the value of IsBusinessCategory in the Categories table, the CHECK constraint will not catch it. You would need to put a separate constraint on the Categories table to catch that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM