sql - 提示 `CHECK` 的语法

标签 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 未绑定(bind)到特定列,而是绑定(bind)到整行,并且可以使用其他行中的值以及以下示例:

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 在语法上绑定(bind)到一个列?我错过了什么吗?

最佳答案

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))

关于sql - 提示 `CHECK` 的语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22133345/

相关文章:

sql - "Order By"使用参数作为列名

mysql - 在sql中使用join的多个总和

sql - SQL中的递归选择

PostgreSQL 将月份名称转换为数字

java - 如何转换为 PostgreSQL 数字类型?

sql - 按期间分组时带入前 12 个月的计数

c# - SqlClient 返回奇怪的 OOM 异常? C#.NET 4

Django 1.5 + Postgres 数据库记录消失

ruby-on-rails - 来自 postgresql 的 Rails 自动轮毫秒查询

mysql - ?喜欢(列 || '%')