2014-03-02 83 views
1

我对CHECK的语法存在问题,特别是它意味着与列一起出现的方式。一个例子来说明这具体:抱怨`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 
) 

CHECK是否出现在v1列或列v2最后这种情况没有什么区别。那么为什么CHECK在语法上与列绑定?我错过了什么?

回答

3

CHECK约束中的表达式不必是单参数函数调用。您可以编写CHECK (v1 > 10)而不是调用您的greater_than_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)) 
+0

这正是我要说的,我给的例子。那么它不是一种糟糕的语法选择,它允许CHECK出现在列的旁边,实际上它适用于整行?而且,当CHECK确实出现在列的旁边时(这暗示开发人员暗示CHECK只使用该列的值?) –

+1

@MarcusJuniusBrutus:这就是SQL标准定义语法的方式。 –

+0

@MarcusJuniusBrutus,列名不能是隐式的,因为您必须编写有效的布尔表达式。你会如何写'CHECK(name = lower(name))'而不提'name'? – Wyzard