【问题标题】:How can I write a CHECK constraint in SQL that allows a series of strings OR a blank value?如何在 SQL 中编写允许一系列字符串或空白值的 CHECK 约束?
【发布时间】:2014-07-18 04:35:01
【问题描述】:

我正在尝试为 SQL 中的一个字段编写一个检查约束,该约束允许一系列字符串(在本例中为省名)或空白值。当前代码是这样的:

ALTER TABLE CODEDLOCATION
ADD CHECK (ADM1='Central' OR ADM1='East' OR ADM1='Far-Western' OR ADM1='Mid-Western' OR ADM1='West')

这适用于 ADM1 字段,但如果新记录中的 ADM1 字段存在空白/空值,则会导致错误。我尝试了以下两个选项,但都不起作用:

ALTER TABLE CODEDLOCATION
ADD CHECK (ADM1='' OR ADM1='Central' OR ADM1='East' OR ADM1='Far-Western' OR ADM1='Mid-Western' OR ADM1='West')

ALTER TABLE CODEDLOCATION
ADD CHECK (ADM1=null OR ADM1='Central' OR ADM1='East' OR ADM1='Far-Western' OR ADM1='Mid-Western' OR ADM1='West')

将 HSQLDB 与 OpenOffice Base 结合使用。谢谢!

附:我在这里使用检查而不是外键约束的原因与使用 OO Base 表单的一些挑战有关...

【问题讨论】:

  • 试试ADM1 IS NULL。您不应在 SQL 中将 NULL= 运算符进行比较。

标签: sql hsqldb ddl check-constraint


【解决方案1】:

nulls 使用 is 运算符进行评估,而不是 = 运算符:

ALTER TABLE CODEDLOCATION
ADD CHECK 
(ADM1 IS null OR 
 ADM1 = 'Central' OR 
 ADM1 = 'East' OR 
 ADM1 = 'Far-Western' OR 
 ADM1 = 'Mid-Western' OR 
 ADM1 = 'West')

【讨论】:

  • 嗯,这很简单:)。工作完美。 (仅等待 10 分钟的最低接受时间)。非常感谢。
【解决方案2】:

从严格建模的 pov 来看,最好的解决方案是查找表并将 ADM1 字段设置为它的外键。 FK 字段可能为空,但如果不是,则必须引用查找表中定义的条目:“Central”、“East”等。

优点是:

  • 如果您拥有或将拥有同一域的另一个字段,它也可以定义为 FK。您不必从此字段中剪切/粘贴检查约束。
  • 如果您必须更改有效值列表,您只需更新查找表。否则,您必须转到所有 ADM1 字段并发出 Alter Table 语句来更改约束。然后(取决于 DBMS)您可以重新编译引用您刚刚更改的表的触发器和 SP。此外,通常情况下,Alter Table 命令保留给 DBA,而您的开发人员应该能够执行插入/更新。

有些人可能会提到的一个缺点是您必须执行连接才能检索字段的内容。很少有足够的影响来考虑问题,尤其是在小型查找表中。连接之于 RDBMS,就像编译之于编程开发​​一样。如果你真的想要,你可以解决它,但你为什么想要呢?

【讨论】:

  • FK 的好解决方案,但没有这样的缺点。无需加入即可检索内容。该字段包含“Central”、“East”等字符串,允许的字符串列表位于查找表中。
  • 好吧,我只是假设将使用键值而不是位置的全文。它可以是代理键或诸如“C”、“E”、“FW”、“MW”、“W”之类的东西。但是,如果将文本本身用作键,那么,是的,您将具有引用完整性而无需加入。但是,如果您这样做并且想要对文本进行任何更改('East' => 'Eastern'),那么您将遇到一个不必要的棘手问题。
  • 可能有一个棘手的问题。您可以级联这样的更改,但许多 DBA 不喜欢这样,因为自动级联会严重影响数据库。
猜你喜欢
  • 2021-02-24
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 1970-01-01
  • 2010-11-23
  • 2023-01-31
  • 2021-05-09
  • 1970-01-01
相关资源
最近更新 更多