九月 13, 2023
摘要:在本教程中,您将了解 PostgreSQL 非空约束以确保列的值不为空。
NULL 简介
在数据库理论中,NULL 代表未知或信息缺失。NULL 与空字符串或数字零不同。
假设您需要将联系人的电子邮件地址插入表中。您可以索取他或她的电子邮件地址。但是,如果您不知道联系人是否有电子邮件地址,则可以在电子邮件地址列中插入 NULL。在这种情况下,NULL 表示在记录时电子邮件地址未知。
NULL 很特别。它不等于任何东西,甚至不等于它本身。表达式NULL = NULL
返回 NULL,因为两个未知值不应该相等是有道理的。
要检查值是否为 NULL,可以使用IS NULL
布尔运算符。例如,如果电子邮件地址中的值为 NULL,则以下表达式返回 true。
email_address IS NULL
IS NOT NULL
运算符对IS NULL
运算符的结果求反。
PostgreSQL NOT NULL 约束
要控制列是否可以接受 NULL,可以使用NOT NULL
约束:
CREATE TABLE table_name(
...
column_name data_type NOT NULL,
...
);
如果列有NOT NULL
约束,则任何在该列中插入或更新 NULL 的尝试都将导致错误。
声明 NOT NULL 列
下面的CREATE TABLE
语句创建一个带有非空约束名为invoices
的新表。
CREATE TABLE invoices(
id SERIAL PRIMARY KEY,
product_id INT NOT NULL,
qty numeric NOT NULL CHECK(qty > 0),
net_price numeric CHECK(net_price > 0)
);
此示例通过在product_id
和qty
列的数据类型后面跟上NOT NULL
关键字,来声明NOT NULL
约束。
请注意,一列可以有多个约束,例如NOT NULL
、CHECK、UNIQUE、FOREIGN KEY 彼此相邻。约束的顺序并不重要。PostgreSQL 可以按任意顺序检查列表中的约束。
如果您使用NULL
而不是NOT NULL
,则该列将接受NULL
和非 NULL 值。如果您没有明确指定NULL
或 NOT NULL
,它将默认接受NULL
。
向现有列添加 NOT NULL 约束
要将NOT NULL
约束添加到现有表的列,请使用以下形式的ALTER TABLE
语句:
ALTER TABLE table_name
ALTER COLUMN column_name SET NOT NULL;
要给多个列添加 NOT NULL 约束,请使用以下语法:
ALTER TABLE table_name
ALTER COLUMN column_name_1 SET NOT NULL,
ALTER COLUMN column_name_2 SET NOT NULL,
...;
让我们看一下下面的例子。
首先,创建一个新表,名为生产订单 ( production_orders
):
CREATE TABLE production_orders (
id SERIAL PRIMARY KEY,
description VARCHAR (40) NOT NULL,
material_id VARCHAR (16),
qty NUMERIC,
start_date DATE,
finish_date DATE
);
接下来,在production_orders
表中插入一个新行:
INSERT INTO production_orders (description)
VALUES('Make for Infosys inc.');
然后,为了确保qty
字段不为空,您可以给qty
列添加非空约束。但是,该列已包含数据。如果您尝试添加非空约束,PostgreSQL 将发出错误。
要将NOT NULL
约束添加到已包含 NULL 的列,您需要首先更新NULL
为非 NULL,如下所示:
UPDATE production_orders
SET qty = 1;
qty
列中的值更新为 1。现在,您可以将NOT NULL
约束添加到qty
列中:
ALTER TABLE production_orders
ALTER COLUMN qty
SET NOT NULL;
之后,您可以更新material_id
、start_date
和finish_date
列的值,以满足非空约束检查:
UPDATE production_orders
SET material_id = 'ABC',
start_date = '2015-09-01',
finish_date = '2015-09-01';
向多列添加非空约束:
ALTER TABLE production_orders
ALTER COLUMN material_id SET NOT NULL,
ALTER COLUMN start_date SET NOT NULL,
ALTER COLUMN finish_date SET NOT NULL;
最后,尝试将qty
列中的值更新为 NULL:
UPDATE production_orders
SET qty = NULL;
PostgreSQL 发出错误消息:
ERROR: null value in column "qty" violates not-null constraint
DETAIL: Failing row contains (1, make for infosys inc., ABC, null, 2015-09-01, 2015-09-01).
NOT NULL 约束的特殊情况
除了NOT NULL
约束之外,您还可以使用 CHECK 约束来强制列接受非 NULL 值。NOT NULL
约束等效于以下CHECK
约束:
CHECK(column IS NOT NULL)
这很有用,因为有时您可能需要a
或b
其中一个列不为空,而不是同时要求两者都不为空。
例如,您可能希望用户表的username
或email
中任一列不为 NULL 或空字符串。在这种情况下,您可以按如下方式使用CHECK
约束:
CREATE TABLE users (
id serial PRIMARY KEY,
username VARCHAR (50),
password VARCHAR (50),
email VARCHAR (50),
CONSTRAINT username_email_notnull CHECK (
NOT (
( username IS NULL OR username = '' )
AND
( email IS NULL OR email = '' )
)
)
);
以下语句有效。
INSERT INTO users (username, email)
VALUES
('user1', NULL),
(NULL, 'email1@example.com'),
('user2', 'email2@example.com'),
('user3', '');
但是,以下语句将执行失败,因为它违反了CHECK
约束:
INSERT INTO users (username, email)
VALUES
(NULL, NULL),
(NULL, ''),
('', NULL),
('', '');
ERROR: new row for relation "users" violates check constraint "username_email_notnull"
概括
-
对列使用
NOT NULL
约束来强制列不接受NULL
。默认情况下,列可以保存 NULL。 -
要检查某个值是否存在
NULL
,可以使用IS NULL
运算符。IS NOT NULL
是IS NULL
取反的结果。 -
切勿使用等于运算符
=
来比较NULL
值,因为它总是返回NULL
。