【问题标题】:Constraint on a column based on values at another column in another table基于另一个表中另一列的值对一列的约束
【发布时间】:2017-09-28 14:27:08
【问题描述】:

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

policy | rule
-------------
1  | A
-------------
1  | B
-------------
2  | C
-------------
3  | D 
-------------

我有另一个带有列 (id) 的表 B。

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

我正在使用 SQL Server,并且正在寻找基于查询的解决方案(不是通过 GUI 步骤)。

【问题讨论】:

  • 我认为您在编写此问题时已经消除了太多实际问题。我不清楚你想在这里实现什么。
  • 您是说如果表 A 中的策略只有 1 行,那么表 B 中的 ID 应该为空?这些表有什么关系?某处需要有一个 ForeignKey ......但是如果我是正确的,这个逻辑应该在查询而不是约束中处理。

标签: sql-server database constraints


【解决方案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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 2020-12-03
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多