使用 Case 语句检查约束

AA.*_*.SC 3 sql-server-2008 sql-server check-constraints

如果列的输入值大于 3,我想在列上添加一个检查约束,而不应将其保存为 1 个其他输入值。对于这种情况,我使用下面的查询,但在插入数据时显示错误消息。

create table tblTestCheckConstraint 
(
id int,
NewColumn int
)


alter table tblTestCheckConstraint
add constraint chk_tblTestCheckConstraint_NewColumn1 CHECK  
(
    CASE
        WHEN NewColumn >4 THEN 1
        ELSE NewColumn
    END = 1
)
Run Code Online (Sandbox Code Playgroud)

插入语句:

insert into tblTestCheckConstraint values ( 1,5)
insert into tblTestCheckConstraint values ( 1,2)
Run Code Online (Sandbox Code Playgroud)

错误信息:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chk_tblTestCheckConstraint_NewColumn1". The conflict occurred in database "DBName"
, table "dbo.tblTestCheckConstraint", column 'NewColumn'.
The statement has been terminated.
Run Code Online (Sandbox Code Playgroud)

Han*_*non 5

检查约束只能用于验证数据是否在给定的参数集内。该CHECK(...)子句本质上是作为布尔条件进行验证的;如果结果为1,则插入该行,如果结果0为 则不插入该行,并向客户端返回错误。

为了对此进行测试,我创建了您的表以及您建议的检查约束,并插入了几行测试数据:

CREATE TABLE dbo.tblTestCheckConstraint /* always specify the schema */
(
id INT,
NewColumn INT
);

ALTER TABLE tblTestCheckConstraint
ADD CONSTRAINT chk_tblTestCheckConstraint_NewColumn1 CHECK  
(
    CASE
        WHEN NewColumn >4 THEN 1
        ELSE NewColumn
    END = 1
);

INSERT INTO dbo.tblTestCheckConstraint (newcolumn) VALUES (1);
INSERT INTO dbo.tblTestCheckConstraint (newcolumn) VALUES (2);
INSERT INTO dbo.tblTestCheckConstraint (newcolumn) VALUES (3);
INSERT INTO dbo.tblTestCheckConstraint (newcolumn) VALUES (5);

SELECT *
FROM dbo.tblTestCheckConstraint;
Run Code Online (Sandbox Code Playgroud)

这会导致几个错误并允许插入两行:

在此处输入图片说明

结果:

在此处输入图片说明

当尝试插入23(或实际上不是1>4)时,约束将返回 false,指示 SQL Server 不执行插入,并返回上面看到的错误消息。

以下是如何使用触发器完成此操作的示例:

USE tempdb

CREATE TABLE dbo.tblTestCheckConstraint 
(
id INT CONSTRAINT PK_tblTestCheckConstring PRIMARY KEY CLUSTERED IDENTITY(1,1),
NewColumn INT NULL
);
GO
CREATE TRIGGER dbo.trg on dbo.tblTestCheckConstraint
INSTEAD OF INSERT
AS 
BEGIN
    INSERT INTO dbo.tblTestCheckConstraint (NewColumn)
    SELECT NewColumn
    FROM INSERTED i
    WHERE i.NewColumn <=3 OR i.NewColumn IS NULL;

    INSERT INTO dbo.tblTestCheckConstraint (NewColumn)
    SELECT 1
    FROM INSERTED i
    WHERE i.NewColumn >3;
END;
GO
INSERT INTO dbo.tblTestCheckConstraint (NewColumn)
VALUES (1);
INSERT INTO dbo.tblTestCheckConstraint (NewColumn)
VALUES (2);
INSERT INTO dbo.tblTestCheckConstraint (NewColumn)
VALUES (3);
INSERT INTO dbo.tblTestCheckConstraint (NewColumn)
VALUES (4);
SELECT *
FROM dbo.tblTestCheckConstraint;
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

确保在尝试插入数据之前从表中删除约束,因为它可能与触发器代码冲突:

ALTER TABLE dbo.tblTestCheckConstraint
DROP CONSTRAINT chk_tblTestCheckConstraint_NewColumn1;
Run Code Online (Sandbox Code Playgroud)