检查约束中的子查询

Hig*_*and 32 sql check-constraints sql-server-2008

我有在SQL-Server2008 R2 设计的桌子.

我在该表中有一个列,在插入数据时需要对另一个表进行检查.

ALTER TABLE Table1
        WITH CHECK ADD CONSTRAINT CK_Code
        CHECK (MyField in (Select Field From Table2))
Run Code Online (Sandbox Code Playgroud)

这会导致错误

在此上下文中不允许子查询.只允许标量表达式.

我看过这个关于Check Constraint的问题- 在这种情况下不允许使用子查询.

有没有办法在不使用触发器的情况下实现这一目标?

Joh*_*son 47

注意,您真正想要的是外键约束.也就是说,要在检查中获得"查询",您可以编写包含查询的函数并输出标量值,然后在检查约束中使用该函数.

CREATE FUNCTION myFunction (
    @field DATATYPE(?)
)
RETURNS VARCHAR(5)
AS
BEGIN
    IF EXISTS (SELECT* FROM Table2 WHERE MYFIELD = @field)
        return 'True'
    return 'False'
END
Run Code Online (Sandbox Code Playgroud)

这样的事情.没有测试过.

然后你可以像这样把它添加到你的支票

ALTER TABLE Table1
    WITH CHECK ADD CONSTRAINT CK_Code
    CHECK (myFunction(MYFIELD) = 'True')
Run Code Online (Sandbox Code Playgroud)

  • @Highland之类的东西?请注意,使用它时可能必须将模式前缀添加到myFunction. (3认同)
  • 这种方法对我有用,在函数名称之前添加了模式前缀(如您的注释中所述)。 (2认同)

Gay*_*ara 7

您不能在检查约束内部进行子查询.你可以做的是使用一个UDF,它返回一个检查约束内的标量值.

第1步:创建表

USE CTBX
GO

CREATE TABLE RawMaterialByGender 
(
RMGID int primary key identity(1,1),
RMID smallint foreign key references RawMaterialMaster(RMID),
LeveLMasterID smallint foreign key references LevelMaster(LevelTextID),
IsDeleted bit
)
Run Code Online (Sandbox Code Playgroud)

第2步:创建返回标量的UDF

Create FUNCTION [dbo].[IsValidLevelMasterGender](@LevelMasterID smallint)

    RETURNS bit
    AS
    BEGIN
     DECLARE @count smallint;
     DECLARE @return bit;

     SELECT @count = count(LevelTextID)      
     FROM [LevelMaster]
     WHERE LevelCategoryID = 3 AND IsActive = 1 AND LevelTextID=@LevelMasterID

     IF(@count = 0)
     SET @return = 'false';
     ELSE
     SET @return = 'true';

     RETURN @return;

    END;
    GO
Run Code Online (Sandbox Code Playgroud)

第3步:更改表以添加CHECK约束

ALTER TABLE RawMaterialByGender 
ADD CONSTRAINT check_LevelMasterID CHECK (dbo.IsValidLevelMasterGender(LeveLMasterID) = 'true')
Run Code Online (Sandbox Code Playgroud)