【问题标题】:how do you enforce conditional not null check across sql columns你如何在 sql 列中强制执行条件非空检查
【发布时间】:2010-01-15 05:28:06
【问题描述】:
create table A (id, col_A, col_B, col_C)

id = 唯一 ID 对于被持久化的每一行,col_A col_B 都会有一个有效值,但两列不会同时为每个持久化的行提供一个值。

例如

insert into A (id, col_A, col_C) values (1, "a", "c")
insert into A (id, col_B, col_C) values (1, "b", "c")
insert into A (id, col_A, col_C) values (1, "aa", "cc")
insert into A (id, col_B, col_C) values (1, "bb", "cc")

注意:根据设计,col_A 和 col_B 不能合并到一个列中。

我想根据上述限制对 col_A 和 col_B 强制执行条件非空检查(即,对于每一行,至少 col_A 或 col_B 应该存在)。我如何做到这一点?

编辑:

  1. 我们希望从 H2、MySQL、Postgres 开始支持以下数据库
  2. 我们还希望通过 JPA 注释而不是特定于数据库的语法来表达约束
  3. 底层 ORM 层是 Hibernate 3.3.x

【问题讨论】:

    标签: sql hibernate database-design jpa


    【解决方案1】:

    您需要定义一个表级检查约束。以下使用 Oracle 语法,但大多数 DBMS 产品会有一些非常相似的东西......

    alter table A add constraint a_or_b
        check (
            ( a is not null and b is null ) 
        or
            ( a is null and b is not null ) 
        )
    /
    

    编辑

    回复你的评论,我猜是

    @org.hibernate.annotations.Check(
    
    constraints = “(a is not null and b is null) or (a is null and b is not null)”
    
    )
    

    但作为数据建模师和 DBA,这确实是我希望在数据库中实施的那种事情。我认为语法在不同风格的 RDBMS 中不会有太大差异(如果有的话)。

    【讨论】:

    • 谢谢,是否可以通过 JPA 注释而不是数据库特定语法来标记此类约束
    【解决方案2】:

    您可以使用检查 col_a 不为 null 或 col_b 不为 null 的约束。如果两列都为空或两列都不为空,这将给您一个错误。它只允许带有 a 或 b 的记录。

    在 SQL Server 中会是这样的:

    ALTER TABLE [dbo].[A]  
    WITH CHECK ADD  CONSTRAINT [CK_test] 
       CHECK  (([col_a] IS NOT NULL and [col_b] IS NULL)
            or ([col_a] IS NULL and [col_b] IS NOT NULL)
            )
    

    【讨论】:

      【解决方案3】:

      触发器。由于您尚未指定哪个数据库,因此很难给出更详细的答案。

      【讨论】:

      • 触发器会起作用,但只有在没有其他方法起作用时才应考虑。在这种情况下,最好使用 CHECK 约束。
      • Jim - 我已编辑问题以添加支持的数据库(H2、MySQL、Postgres)。但我正在寻找一种独立于数据库的方式来创建此类约束
      猜你喜欢
      • 2011-01-21
      • 2014-05-22
      • 2012-03-20
      • 1970-01-01
      • 2011-05-06
      • 1970-01-01
      • 2017-10-01
      • 2018-11-29
      • 2020-05-01
      相关资源
      最近更新 更多