简体   繁体   English

检查约束中的子查询

[英]Sub queries in check constraint

I have table designed in SQL-Server 2008 R2. 我有在SQL-Server 2008 R2中设计的表。

I have a column in that table which needs to be checked against another table when data is inserting. 我在该表中有一列,在插入数据时需要对照另一张表进行检查。

ALTER TABLE Table1
        WITH CHECK ADD CONSTRAINT CK_Code
        CHECK (MyField in (Select Field From Table2))

This cause an error 这会导致错误

Sub-queries are not allowed in this context. 在这种情况下,不允许子查询。 Only scalar expressions are allowed. 仅允许标量表达式。

I have looked at this question about Check Constraint - Subqueries are not allowed in this context . 我已经看过有关检查约束的问题-在这种情况下不允许子查询

Is there any way of achieving this without using a trigger? 有没有不用触发器就可以实现这一目标的方法?

Note, what you really want is a foreign key constraint. 注意,您真正想要的是外键约束。 That said, to get a "query" into a check you can write a function that contains the query and outputs a scalar value, then use that function in the check constraint. 也就是说,要使“查询”进入检查,您可以编写一个包含查询并输出标量值的函数,然后在检查约束中使用该函数。

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

Something like that. 这样的事情。 Not tested. 未经测试。

Then you can add it to your check like so 然后您可以像这样将其添加到您的支票中

ALTER TABLE Table1
    WITH CHECK ADD CONSTRAINT CK_Code
    CHECK (myFunction(MYFIELD) = 'True')

You can't have sub queries inside check constraints. 检查约束中不能有子查询。 What you can do is use a UDF that returns a scalar value inside the check constraint. 您可以使用UDF在检查约束内返回标量值。

Step 1: Create the table 步骤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
)

Step 2 : Create the UDF that returns a scalar 第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

Step 3 : Alter table to add the CHECK constraint 步骤3:修改表以添加CHECK约束

ALTER TABLE RawMaterialByGender 
ADD CONSTRAINT check_LevelMasterID CHECK (dbo.IsValidLevelMasterGender(LeveLMasterID) = 'true')
ALTER TABLE Table1
ADD CONSTRAINT FK_Table1_Code FOREIGN KEY (MyField)
REFERENCES Table2 (Field) ;

Ref: http://msdn.microsoft.com/en-us/library/ms190273.aspx 参考: http : //msdn.microsoft.com/en-us/library/ms190273.aspx
Note: I haven't checked the above for syntax. 注意:我没有检查上面的语法。

First of all in your example you clearly need FK Constraint. 首先,在您的示例中,您显然需要FK约束。

Another posibility is to use view with WITH CHECK OPTION and give access to user through it: 另一个可能性是将视图与WITH CHECK OPTION一起WITH CHECK OPTION并通过它授予用户访问权限:

CREATE TABLE Table1(i INT PRIMARY KEY, CK_Code CHAR(1));
CREATE TABLE Table2(Field CHAR(1));
INSERT INTO Table2(Field) VALUES ('A'),('B'), ('C');
GO

CREATE VIEW v_Table1
AS
SELECT *
FROM Table1
WHERE CK_code IN (SELECT Field FROM Table2)  -- here goes your subquery check
WITH CHECK OPTION;

When you try to insert data that violates your "constraint" like: 当您尝试插入违反“约束”的数据时,例如:

INSERT INTO v_Table1(i, CK_Code)
VALUES(10, 'D');

You will get: 你会得到:

The attempted insert or update failed because the target view either specifies WITH CHECK OPTION or spans a view that specifies WITH CHECK OPTION and one or more rows resulting from the operation did not qualify under the CHECK OPTION constraint. 尝试插入或更新失败,因为目标视图要么指定了WITH CHECK OPTION,要么跨越了一个指定WITH CHECK OPTION的视图,并且该操作产生的一个或多个行不符合CHECK OPTION约束。

The statement has been terminated. 该语句已终止。

LiveDemo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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