检查具有动态列表的约束

use*_*105 3 sql-server

我需要创建一个检查约束,我面临的问题是约束接受的值列表在未来会发生变化(例如:现在“红色,绿色和蓝色”在下个月“红色,绿色,蓝色和白色” )。这该怎么做 ?

Mar*_*ith 9

您应该使用外键约束来执行此操作。

您可以使用以下定义创建检查约束

CREATE TABLE T
(
Color varchar(10) CHECK (Color in ('red','green','blue'))
)
Run Code Online (Sandbox Code Playgroud)

但是没有办法改变检查约束定义而不删除它并重新创建它(因此需要根据新定义重新验证所有行)

要修改CHECK约束,您必须首先删除现有CHECK 约束,然后使用新定义重新创建它。

这与外键约束无关

CREATE TABLE Colors
  (
     Color VARCHAR(10) PRIMARY KEY
  )

INSERT INTO Colors
VALUES      ('red'),
            ('green'),
            ('blue')

CREATE TABLE T
  (
     Color VARCHAR(10) REFERENCES Colors
  ) 
Run Code Online (Sandbox Code Playgroud)

虽然我可能会在Colors表中引入一个代理键,而不是在主表中重复存储字符串。

我之前遇到过一个论点,即使用检查约束在某种程度上比使用外键和查找表“更正确”,但查找表对我的优势是。

  1. 将项目添加到列表更容易、更有效。
  2. 更容易获得不同的允许颜色列表(例如,在应用程序的列表框中显示)
  3. 与可变长度字符串相比,使用固定长度的整数代理键可以在减少行大小和避免更新碎片方面具有性能优势。

注意:可以让检查约束引用一个标量 UDF,而该标量 UDF 又引用一个表,但应避免这种方法。它没有正确模拟外键(例如不验证DELETE FROM Colors

  • @user2080105:你为什么认为那很奇怪?这是在关系数据库中对此类约束进行建模的标准方法。 (3认同)
  • @ user2080105 - 那么你显然冒着获取无效数据的风险,例如存储“鱼”而不是预期的颜色。 (2认同)