【问题标题】:Why `IF` clause is not possible in postgres `CHECK` constraint?为什么在 postgres `CHECK` 约束中不能使用 `IF` 子句?
【发布时间】:2020-01-31 22:22:06
【问题描述】:

例如,这个查询是否可行?

CREATE TABLE products (
    name text,
    price numeric not null,
    CHECK (IF price > 0 THEN name IS NOT NULL ELSE name IS NULL END IF)
);

更新:

好像没有

这里https://rextester.com/l/postgresql_online_compiler

报错

Error(s), warning(s):

42601: syntax error at or near "price"

查看文档 https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE 它说

目前,CHECK 表达式不能包含子查询,也不能引用当前行列以外的变量。可以引用系统列 tableoid,但不能引用任何其他系统列。

但是IF不是子查询,不明白为什么不起作用


更新 2:

CREATE TABLE products (
    name text,
    price numeric not null,
    CHECK ((price > 0 AND name IS NOT NULL) OR (price <= 0 AND name IS NULL))
);

有效,但是以这种方式编写复杂的查询很乏味

【问题讨论】:

  • 在您的具体情况下,((price &gt; 0) = (name IS NOT NULL)) 将是最简洁的方式,您可能希望选择 then 和 else 分支不相关的示例。

标签: postgresql ddl check-constraints


【解决方案1】:

IF 不是子查询,在 SQL 中也不是其他任何东西。所以假设它是一个列名。连续有两个(假定的)列名是语法错误,并分配给第二个列名。

SQL 有 CASE,而不是 IF。你需要使用你正在使用的语言,而不仅仅是编造你希望工作的东西。

CREATE TABLE products (
    name text,
    price numeric not null,
    CHECK (case when price > 0 THEN name IS NOT NULL ELSE name IS NULL END)
);

【讨论】:

    【解决方案2】:

    我不是 100% 理解你的要求,但我认为你是在说:

    If the price > 0 then name CANNOT be NULL
    

    在这种情况下应该这样做:

    CHECK (price > 0 AND name IS NOT NULL)
    

    如果 nameprice 为 0 时可以为 NULL,则使用此:

    CHECK ((price > 0 AND name IS NOT NULL) OR (price = 0 AND name IS NULL))
    

    您不需要在CHECK 条件中指定IF,它本质上应该包含要测试的实际语句,而不是IF 语句。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-01
      • 2013-05-06
      • 1970-01-01
      • 2014-02-27
      • 1970-01-01
      • 2012-06-11
      • 2019-11-20
      • 1970-01-01
      相关资源
      最近更新 更多