基于另一个表

时间:2017-09-28 14:27:08

标签: sql-server database constraints

我有一个表A,它有两列,策略和规则。表值如下:

政策|规则

1 | A

1 |乙

2 | ç

3 | d

我有另一个表B,我是否有列(id)。

我想在列(id)上对此表B写一个约束,这样如果表A中不同策略的数量等于1,那么(id)的值应该总是为NULL。

我正在使用SQL Server,我正在研究基于查询的解决方案(不是通过GUI步骤)。 请帮忙。

1 个答案:

答案 0 :(得分:1)

将CHECK约束添加到表

create table tableA (policy int , [rule] char(1)) 
create table tableB (Id int , policy int ) 
GO

查看约束的函数

CREATE FUNCTION CheckFnctn(@policy int) -- Adapt if necessary
RETURNS bit
AS 
BEGIN
DECLARE @retval bit = 1
IF EXISTS(SELECT TOP 1 1 FROM tableA WHERE policy = @policy and policy = 1)
BEGIN
    RETURN 0
END
RETURN @retval

END;
GO

将约束添加到表

ALTER TABLE tableB ADD CONSTRAINT ck_id_policy_1 CHECK (dbo.CheckFnctn(policy) = 1) 

测试

    INSERT tableA Values
     (1,'A')
    ,(1,'B')
    ,(2,'B')
    ,(2,'D')
GO
    (4 row(s) affected)


INSERT tableB (Id, policy) values (1,2)
GO
(1 row(s) affected)


INSERT tableB (Id, policy) values (1,1)
GO
Msg 547, Level 16, State 0, Line 2
The INSERT statement conflicted with the CHECK constraint "ck_id_policy_1". The conflict occurred in database "XXXX", table "dbo.tableB", column 'policy'.
The statement has been terminated.

如果需要检查是否存在策略1,则永远不能插入与null不同的ID。使用此功能和约束

CREATE FUNCTION CheckFnctn(@Id int)
RETURNS bit
AS 
BEGIN
DECLARE @retval bit = 1
IF EXISTS(SELECT TOP 1 1 FROM tableA WHERE  policy = 1 AND @Id IS NOT NULL)
BEGIN
    RETURN 0
END
RETURN @retval

END;
GO



ALTER TABLE tableB ADD CONSTRAINT ck_id_policy_1 CHECK (dbo.CheckFnctn(Id) = 1) 

INSERT tableB (Id, policy) values (1,2)
GO
Msg 547, Level 16, State 0, Line 3
The INSERT statement conflicted with the CHECK constraint "ck_id_policy_1". The conflict occurred in database "XXXXX", table "dbo.tableB", column 'Id'.
The statement has been terminated.

INSERT tableB (Id, policy) values (NULL,1)
GO
(1 row(s) affected)