大鹏网络网站建设报价asp 建站
摘要: 在本教程中,你将学习如何使用 PostgreSQL 的 CHECK 约束来确保表列中的值满足某个条件。
PostgreSQL CHECK 约束简介
PostgreSQL 的 CHECK 约束通过确保列中的值必须满足布尔表达式来维护数据完整性。
当列具有 CHECK 约束时,如果您尝试插入或更新导致布尔表达式为 false 的值,PostgreSQL 会发出约束冲突并拒绝这些更改。
CHECK 约束有助于在数据库级别实施数据完整性规则。它们可以防止向表列中插入或更新无效数据。
例如,你可以使用 CHECK 约束来防止向 price 列或 products 表中插入负值。
以下是 CHECK 约束的语法:
CREATE TABLE table_name (column1 data_type CONSTRAINT constraint_name CHECK(boolean_expression),...);
在此语法中:
- 首先,向表列添加一个
CHECK约束。 - 其次,在
CONSTRAINT关键字后提供一个约束名称。如果发生约束违反错误,该约束名称将在错误信息中显示。如果不提供约束名称,PostgreSQL会为该约束隐式生成一个名称。 - 第三,在
CHECK关键字后面的括号()中放入一个布尔表达式,用于检查要插入或更新到列中的值。该布尔表达式可以引用同一张表的列,而不能引用其他表的列。
以下是不使用约束名称的更简洁语法:
CREATE TABLE table_name (column1 data_type CHECK(boolean_expression),...
);
这个 CHECK 约束是列约束,因为它附加到特定的列 (column1) 。
值得注意的是,您可以对同一列应用多个约束。例如,您可以对同一列同时使用 NOT NULL 和 CHECK 约束:
CREATE TABLE table_name (column1 data_type NOT NULL CHECK(boolean_expression),...
);
或者,您可以将 CHECK 约束定义为表约束:
CREATE TABLE table_name (column1 data_type NOT NULL,...,CHECK(boolean_expression)
);
在这种语法中,您要在列列表之后定义 CHECK 约束。当在布尔表达式中引用多个表列时,这种语法很方便。
基本的 PostgreSQL CHECK 约束示例
首先,创建一个表,名为 products ,并添加一个 CHECK 约束,以确保价格大于或等于0:
CREATE TABLE products (product_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,name VARCHAR(255) NOT NULL,price DEC(11, 2) NOT NULL CONSTRAINT positive_price CHECK (price >= 0),discounted_price DEC(11, 2) NOT NULL DEFAULT 0
);
接下来,尝试向 products 表中插入一行包含负价格的数据:
INSERT INTOproducts (name, price)
VALUES('iPhone Pro 15', -1299.99);
PostgreSQL 发出了以下错误:
new row for relation "products" violates check constraint "positive_price"
然后,插入一行包含有效价格的新记录:
INSERT INTOproducts (name, price)
VALUES('iPhone Pro 15', 1299.99) RETURNING *;
输出:
product_id | name | price | discounted_price
------------+---------------+---------+------------------2 | iPhone Pro 15 | 1299.99 | 0.00
之后,将价格更新为无效值:
UPDATE products
SETprice = -899.99
WHEREproduct_id = 2;
PostgreSQL 发出了相同的检查约束冲突:
new row for relation "products" violates check constraint "positive_price"
最后,将价格更新为有效的价格:
UPDATE products
SETprice = 999.99
WHEREproduct_id = 2
RETURNING *;
输出:
product_id | name | price | discounted_price
------------+---------------+--------+------------------2 | iPhone Pro 15 | 999.99 | 0.00
输出表明该语句已成功更新产品价格。
为表添加 CHECK 约束
您可以使用 ALTER TABLE ... ADD CONSTRAINT 语句向现有表添加 CHECK 约束。
以下是该语句的语法:
ALTER TABLE table_name
ADD CONSTRAINT constraint_name
CHECK (boolean_expression)
例如,以下语句添加了一个 CHECK 约束,用于检查折扣价是否低于原价:
ALTER TABLE products
ADD CONSTRAINT discounted_price_check
CHECK (discounted_price < price AND discounted_price > 0);
PostgreSQL 会发出错误,因为表中的某些行违反了新的 CHECK 约束:
check constraint "discounted_price_check" of relation "products" is violated by some row
原因是行 ID 2 的折扣价为 0 ,这违反了新的 CHECK 约束。
要解决此问题,你可以更新现有行的折扣价格,使其符合新的 CHECK 约束:
UPDATE products
SET discounted_price = price * 0.9
RETURNING *;
输出:
product_id | name | price | discounted_price
------------+---------------+--------+------------------2 | iPhone Pro 15 | 999.99 | 899.99
然后再次向 products 表添加 CHECK 约束:
ALTER TABLE products
ADD CONSTRAINT discounted_price_check
CHECK (discounted_price < price AND discounted_price > 0);
如果您尝试插入一行数据,其中折扣价高于或等于原价,PostgreSQL 会发出检查违规提示。例如:
INSERT INTO products(name, price, discounted_price)
VALUES('iPhone Pro 15', 1299.99, 1399.99);
错误:
ERROR: new row for relation "products" violates check constraint "discounted_price_check"
从表中删除 CHECK 约束
要从表中删除 CHECK 约束,需使用 ALTER TABLE ... DROP CONSTRAINT 语句:
ALTER TABLE table_name
DROP CONSTRAINT IF EXISTS constraint_name;
在此语法中:
- 首先,指定你要从中移除
CHECK约束的表名。 - 其次,在
DROP CONSTRAINT子句中提供要删除的约束名称。 - 第三,使用可选的
IF EXISTS选项,以防止因尝试删除不存在的CHECK约束而出现错误。
例如,以下语句会从 products 表中删除 discounted_price 的 CHECK 约束:
ALTER TABLE products
DROP CONSTRAINT IF EXISTS discounted_price_check;
结论
CHECK约束向表中的一个或多个列添加验证逻辑,以确保数据完整性。- 使用
CONSTRAINT ... CHECK为表定义一个CHECK约束。 - 使用
ALTER TABLE ... ADD CONSTRAINT语句向表中添加CHECK约束。 - 使用
ALTER TABLE ... DROP CONSTRAINT语句从表中删除CHECK约束。
