抱怨`CHECK`的语法

时间:2014-03-02 20:54:36

标签: sql postgresql

我对CHECK的语法有疑问,特别是它与列一起显示的方式。这个具体的一个例子:

CREATE OR REPLACE FUNCTION greater_than_10(x INTEGER) RETURNS BOOLEAN AS
'SELECT $1>10;'
LANGUAGE SQL; 

CREATE TABLE A (
    v1 INTEGER CHECK (greater_than_10(v1)),
    v2 INTEGER CHECK (greater_than_10(v2))
)

以下是我的问题:为什么CHECK必须与列一起显示?如果它只是出现在列旁边,那么传递参数是多余的,因为该列的值应该是隐含的。但是,以下语法同样正确:

CREATE TABLE A (
    v1 INTEGER CHECK (greater_than_10(v2)),
    v2 INTEGER CHECK (greater_than_10(v1))
)

表明CHECK未绑定到特定列,而是绑定到整个行,并且可以使用其他行以及以下示例中的值:

CREATE OR REPLACE FUNCTION sum_more_than_10(x INTEGER, y INTEGER) RETURNS BOOLEAN AS
'SELECT $1+$2>10;'
LANGUAGE SQL;         

CREATE TABLE A (
    v1 INTEGER CHECK (sum_more_than_10(v1, v2)),
    v2 INTEGER 
)

在最后一种情况下,CHECKv1或列v2中是否显示没有区别。那么为什么CHECK在句法上绑定到列?我错过了什么吗?

1 个答案:

答案 0 :(得分:3)

CHECK约束中的表达式不必是单参数函数调用。您可以只编写greater_than_10,而不是调用CHECK (v1 > 10)函数。或者你可以写CHECK (20 < (v1 * 2))。列名可以出现在表达式的任何位置;它并不意味着在任何特定的地方。

此外,列约束实际上只是表约束的语法糖。当你写

v1 INTEGER CHECK (v1 > 10),
v2 INTEGER CHECK (v2 > 10)

它相当于写作

v1 INTEGER,
v2 INTEGER,
CHECK (v1 > 10),
CHECK (v2 > 10)

您甚至可以将两者合并为一个约束:

v1 INTEGER,
v2 INTEGER,
CHECK ((v1 > 10) AND (v2 > 10))