【问题标题】:NOT NULL constraint over a set of columns对一组列的 NOT NULL 约束
【发布时间】:2014-01-28 01:20:28
【问题描述】:

我在 Postgres 中有一个表,该表当前在其 email 列上有一个 NOT NULL 约束。该表还有一个可选的phone 列。我希望系统接受一些没有email 的记录,但前提是这些记录具有phone 作为NOT NULL。换句话说,我需要一个NOT NULL 数据库约束,这样如果emailphone 字段中的一个或两个都存在,则CREATEUPDATE 查询成功而不会出现任何错误。

进一步扩展上述内容,是否可以在 Postgres 中指定一组列名,其中一个或多个应为 NOT NULL 才能成功更新或创建记录?

【问题讨论】:

    标签: sql database postgresql constraints postgresql-9.2


    【解决方案1】:

    @Igor is quite right 和几个OR'ed 表达式既快速又简单。

    对于很长的列列表(在示例中为abcdefg),这更短且同样快速:

    CHECK (NOT (a,b,c,d,e,f,g) IS NULL)
    

    db小提琴here
    sqlfiddle

    它是如何工作的?

    上述更详细的形式是:

    CHECK (NOT ROW(a,b,c,d,e,f,g) IS NULL)
    

    ROW 在这里是多余的语法。

    使用IS NULL 测试ROW 表达式 如果每一列 都是NULL,则报告TRUE - 这恰好是我们想要的排除。

    不可能简单地用(a,b,c,d,e,f,g) IS NOT NULL 反转这个表达式,因为这会测试每一列IS NOT NULL。相反,用NOT 否定整个表达式。瞧。

    手册herehere中的更多详细信息。

    形式的表达:

    CHECK (COALESCE(a,b,c,d,e,f,g) IS NOT NULL)
    

    会达到同样的效果,但不那么优雅并且有一个主要限制:仅适用于 匹配数据类型的列,而对 ROW 表达式的检查适用于 any 列。

    【讨论】:

      【解决方案2】:

      您可以为此使用CHECK 约束。 比如:

      CHECK (email is not null OR phone is not null)
      

      有关约束的详细信息可以找到here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-22
        • 1970-01-01
        • 2020-10-16
        • 2023-02-03
        • 1970-01-01
        • 2020-05-09
        • 2018-08-24
        相关资源
        最近更新 更多