如何跨sql列强制执行条件非空检查

时间:2010-01-15 05:28:06

标签: sql hibernate database-design jpa

create table A (id, col_A, col_B, col_C)

id =唯一ID 对于要保留的每一行,col_A col_B将具有有效值,但两个列不会同时为每个持久行创建值。

e.g。

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

3 个答案:

答案 0 :(得分:5)

您需要定义表级检查约束。以下使用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的不同风格上会有很大差异,如果有的话。

答案 1 :(得分:2)

您可以使用检查col_a不为null或col_b不为null的约束。如果两列都为null或两列都不为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)
        )

答案 2 :(得分:0)

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