SQL - 检查约束:数据完整性的友好指南

你好,未来的SQL法师们!今天,我们将深入SQL检查约束的神奇世界。如果你是编程新手,不用担心——我会成为你的向导,带着你一步步探险。所以,拿起你最喜欢的饮料,舒服地坐好,让我们开始这段旅程!

SQL - Check Constraint

SQL CHECK约束:你数据的最佳朋友

想象一下你在组织一个派对,你希望确保只有18岁以上的客人才能参加。CHECK约束对你的数据库做的就是这件事——它像一个门卫,确保只有正确的数据才能进入!

CHECK约束是我们设置在表中的列(或列)上的规则,以确保在数据被允许进入之前,它满足某些条件。这就好像给数据库赋予了一种超能力,以保持数据的完整性!

让我们看一些例子来使这一点更清晰。

单列上的CHECK约束:独奏表演

当我们将CHECK约束应用于单个列时,我们是在告诉该列:“喂,你有一个任务——确保数据遵循这个规则!”

以下是一个例子:

CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50),
Age INT CHECK (Age >= 18)
);

在这个例子中,我们在Employees表的Age列上创建了一个CHECK约束。这个约束确保输入的任何年龄都必须是18岁或以上。如果有人试图插入一个18岁以下的员工,数据库会礼貌地拒绝,就像我们的派对门卫一样!

让我们尝试插入一些数据:

-- 这将成功
INSERT INTO Employees (EmployeeID, FirstName, LastName, Age)
VALUES (1, 'John', 'Doe', 25);

-- 这将失败
INSERT INTO Employees (EmployeeID, FirstName, LastName, Age)
VALUES (2, 'Jane', 'Smith', 17);

第一个INSERT语句将成功,因为25大于或等于18。然而,第二个会失败,因为17不满足我们的CHECK约束。我们的数据门卫正在做它的工作!

多列上的CHECK约束:动态二人组

有时,我们需要检查一个涉及多个列的条件。这时,多列CHECK约束就派上用场了!

以下是一个例子:

CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
OrderDate DATE,
ShipDate DATE,
CHECK (ShipDate >= OrderDate)
);

在这个Orders表中,我们确保ShipDate总是在OrderDate或之后。毕竟,我们不可能在订单下单之前就发货,对吧?那将需要时间旅行,而SQL还没有那么先进...至少现在还没有!

让我们试试看:

-- 这将成功
INSERT INTO Orders (OrderID, OrderDate, ShipDate)
VALUES (1, '2023-06-01', '2023-06-03');

-- 这将失败
INSERT INTO Orders (OrderID, OrderDate, ShipDate)
VALUES (2, '2023-06-01', '2023-05-31');

第一个INSERT没有问题,因为ShipDate(6月3日)在OrderDate(6月1日)之后。第二个INSERT失败了,因为它试图在订单(5月31日)下单之前发货。我们的时间警察CHECK约束捕捉到了这个时间异常!

表级CHECK约束:全知之眼

有时,我们希望创建一个涉及多个列但不绑定到任何特定列的CHECK约束。我们可以通过创建一个表级约束来实现。

以下是如何操作的:

CREATE TABLE Products (
ProductID INT PRIMARY KEY,
ProductName VARCHAR(50),
UnitPrice DECIMAL(10,2),
DiscountedPrice DECIMAL(10,2),
CONSTRAINT CHK_Price CHECK (DiscountedPrice <= UnitPrice)
);

在这个Products表中,我们确保DiscountedPrice总是小于或等于UnitPrice。毕竟,我们不想在打折后意外地提高了产品的价格!

让我们看看它是如何工作的:

-- 这将成功
INSERT INTO Products (ProductID, ProductName, UnitPrice, DiscountedPrice)
VALUES (1, 'Super Gadget', 99.99, 79.99);

-- 这将失败
INSERT INTO Products (ProductID, ProductName, UnitPrice, DiscountedPrice)
VALUES (2, 'Mega Widget', 49.99, 59.99);

第一个INSERT成功了,因为DiscountedPrice(79.99)小于UnitPrice(99.99)。第二个INSERT失败了,因为它试图设置一个高于UnitPrice(49.99)的DiscountedPrice(59.99)。我们的CHECK约束拯救了我们免受这种定价错误的困扰!

对现有列添加CHECK约束:改造

如果我们已经有了表并希望添加CHECK约束怎么办?没问题!我们也可以向现有列添加约束。

以下是如何操作的:

-- 首先,让我们创建一个没有约束的表
CREATE TABLE Students (
StudentID INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50),
GPA DECIMAL(3,2)
);

-- 现在,让我们添加一个CHECK约束
ALTER TABLE Students
ADD CONSTRAINT CHK_GPA CHECK (GPA >= 0.0 AND GPA <= 4.0);

在这个例子中,我们添加了一个CHECK约束以确保GPA总是在0.0到4.0之间。

让我们测试一下:

-- 这将成功
INSERT INTO Students (StudentID, FirstName, LastName, GPA)
VALUES (1, 'Alice', 'Johnson', 3.75);

-- 这将失败
INSERT INTO Students (StudentID, FirstName, LastName, GPA)
VALUES (2, 'Bob', 'Smith', 4.5);

第一个INSERT成功了,因为3.75在我们允许的GPA范围内。第二个INSERT失败了,因为4.5超过了我们的最大值4.0。我们改造后的CHECK约束在保持GPA方面做得很好!

删除CHECK约束:大逃亡

有时,我们可能需要删除CHECK约束。也许我们的业务规则已经改变,或者我们正在重构数据库。无论原因是什么,SQL都为我们提供了一种删除约束的方法。

以下是如何操作的:

-- 删除命名约束
ALTER TABLE Students
DROP CONSTRAINT CHK_GPA;

-- 删除未命名约束(SQL Server语法)
ALTER TABLE Employees
DROP CONSTRAINT ALL;

就这样,约束消失了!但是记住,能力越大,责任越大。在删除约束之前,确保你真的想这么做!

结论:你的数据完整性工具箱

就这样,各位!我们已经穿越了SQL CHECK约束的土地,从单列守卫到多列哨兵,从表级监督者到约束移除者。

记住,CHECK约束就像是你的数据王国的忠诚守护者。它们不知疲倦地确保只有正确的数据进入你的表,保持你的数据库干净、一致和可靠。

在你继续SQL探险的过程中,请将这些CHECK约束放入你的工具箱。它们将是你在维护数据完整性和防止那些讨厌的数据小妖精潜入时的忠实伙伴!

现在,勇敢地前进,充满信心地约束吧!快乐SQL!

方法 描述 示例
单列检查 对单个列应用条件 Age INT CHECK (Age >= 18)
多列检查 对涉及多个列的条件应用 CHECK (ShipDate >= OrderDate)
表级检查 在表级别应用条件 CONSTRAINT CHK_Price CHECK (DiscountedPrice <= UnitPrice)
向现有列添加检查 向现有列添加CHECK约束 ALTER TABLE Students ADD CONSTRAINT CHK_GPA CHECK (GPA >= 0.0 AND GPA <= 4.0)
删除检查约束 删除现有的CHECK约束 ALTER TABLE Students DROP CONSTRAINT CHK_GPA

Credits: Image by storyset