提要:在本教程中,我们将向您介绍 CHECK 约束,基于布尔表达式来约束字段的值。

CHECK 约束是约束的一种,允许你指定字段的值必须满足的条件。CHECK 约束使用布尔表达式来判断字段的值。如果字段的通过了检查,PostgreSQL 将把该值插入或更新。

在新表中定义 CHECK 约束

我们通常在使用 CREATE TABLE 语句创建表的时候来定义 CHECK 约束。下面的例子定义了 employees 表:

CREATE TABLE employees (
 id serial PRIMARY KEY,
 first_name VARCHAR (50),
 last_name VARCHAR (50),
 birth_date DATE CHECK (birth_date > '1900-01-01'),
 joined_date DATE CHECK (joined_date > birth_date),
 salary numeric CHECK(salary > 0)
);

employees 表有三个 CHECK 约束

  • 员工的出生日期(birth_date)必须大于 1900-01-01,如果你尝试插入一个 1900-01-01 之前的数据,将会报错
  • 入职日期(joined_date)必须大于出生日期
  • 第三,很显然,工资(salary)必须大于0

现在,尝试往 employees 表插入新数据:

INSERT INTO employees (
 first_name,
 last_name,
 birth_date,
 joined_date,
 salary
)
VALUES
 (
 'John',
 'Doe',
 '1972-01-01',
 '2015-07-01', 
                -100000
 )

我们想往表里插入一条工资为负数的记录,PostgreSQL 返回了错误:

[Err] ERROR:  new row for relation "employees" violates check constraint "employees_salary_check"
DETAIL:  Failing row contains (1, John, Doe, 1972-01-01, 2015-07-01, -100000).

默认,PostgreSQL 使用以下模式给 CHECK 约束 命名:

{table}_{column}_check

如果要给约束指定名称,可以在 CONSTRAINT 后面指定:

salary numeric CONSTRAINT positive_salary CHECK(salary > 0),

给已存在的表定义 CHECK 约束

要给已存在的表定义 CHECK 约束,需要使用 ALTER TABLE 语句。假设,我们已经有一张名为 prices_list 的表,其定义如下:

CREATE TABLE prices_list (
 id serial PRIMARY KEY,
 product_id INT NOT NULL,
 price NUMERIC NOT NULL,
 discount NUMERIC NOT NULL,
 valid_from DATE NOT NULL,
 valid_to DATE NOT NULL
);

现在,给这张表定义 CHECK 约束

  • 价格 price 必须大于0
  • 折扣 discount 必须大于等于0
  • 价格必须大于折扣

SQL 语句如下:

ALTER TABLE prices_list ADD CONSTRAINT price_discount_check CHECK (
 price > 0
 AND discount >= 0
 AND price > discount
);

另外,有效期的结束时间 valid_to 必须大于等于有效期的开始时间 valid_from

ALTER TABLE prices_list 
ADD CONSTRAINT valid_range_check CHECK (valid_to >= valid_from);
上一篇:PostgreSQL 清空表