为什么 postgres `CHECK` 约束中不能使用 `IF` 子句?

srg*_*hma 4 postgresql ddl check-constraints

例如这个查询可能吗?

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

更新:

好像没有

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

它抛出错误

Error(s), warning(s):

42601: syntax error at or near "price"
Run Code Online (Sandbox Code Playgroud)

查看文档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))
);
Run Code Online (Sandbox Code Playgroud)

可行,但以这种方式编写复杂的查询会很乏味

jja*_*nes 9

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

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)
);
Run Code Online (Sandbox Code Playgroud)