Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - SQL 的用法 » 创建数据库 » 确保数据完整性 » 实施实体完整性和参照完整性 » 参照完整性检查

 

执行 DELETE 或 UPDATE 时检查完整性

在执行更新或删除操作时也可能引起外键错误。例如,假设您尝试从 Departments 表中删除研发部。DepartmentID 字段作为 Departments 表的主键,构成了一对多关系中的 "一" 方(Employees 表的 DepartmentID 字段是相应的外键,构成了 "多" 方)。在关系中的 [多] 方上的所有相应记录未全部删除前,不可以删除 [一] 方上的记录。

执行 DELETE 时的参照完整性错误

假设尝试删除 Departments 表中的研发部 (DepartmentID 100)。将报告一个错误,指出在数据库中有其它记录引用了研发部,因此未执行删除操作。若要删除研发部,需要先删除该部门中的所有雇员,操作如下:

DELETE
FROM Employees
WHERE DepartmentID = 100;

由于已删除了属于研发部的所有雇员,现在可以删除研发部了:

DELETE 
FROM Departments 
WHERE DepartmentID = 100;

输入 ROLLBACK 语句取消对数据库的这些更改:

ROLLBACK;
执行 UPDATE 时的参照完整性错误

现在,假设您尝试更改 Employees 表的 DepartmentID 字段。DepartmentID 字段作为 Employees 表的外键,构成了一对多关系中的 "多" 方(Departments 表的 DepartmentID 字段是相应的主键,构成了 "一" 方)。关系的 [多] 方上的记录不能更改,除非它对应于 [一] 方上的记录。也即,除非它有一个用于引用的主键。

例如,以下 UPDATE 语句会导致完整性错误:

UPDATE Employees
SET DepartmentID = 600
WHERE DepartmentID = 100;

这会引发错误 [表 'Employees' 中的外键 'FK_DepartmentID_DepartmentID' 没有主键值],因为 Departments 表中没有 DepartmentID 为 600 的部门。

若要更改 Employees 表中 DepartmentID 字段的值,它必须对应于 Departments 表中已经存在的值。例如:

UPDATE Employees
SET DepartmentID = 300
WHERE DepartmentID = 100;

此语句可以执行,因为字段 DepartmentID 的值 300 对应于已经存在的财务部。

输入 ROLLBACK 语句取消对数据库的这些更改:

ROLLBACK;
在提交时检查完整性

在上述示例中,都在执行每一命令时检查数据库的完整性。任何会导致数据库不一致的操作都不会执行。

可以使用 wait_for_commit 选项将数据库配置为在提交前不检查完整性。如果在发生更改时您需要进行可能会导致数据暂时不一致的更改,这会非常有用。例如,假设您要删除 Employees 和 Departments 表中的研发部。由于这些表互相引用且必须一次对一个表进行删除,因此在删除期间表之间会出现不一致。这种情况下,数据库在完成删除前无法执行 COMMIT。将 wait_for_commit 选项设置为 On,以在执行提交前允许存在数据不一致情况。请参见wait_for_commit 选项 [数据库]

您也可以将外键定义为能自动进行修改以与主键的更改保持一致。在上例中,如果已使用 ON DELETE CASCADE 定义从 Employees 到 Departments 的外键,则若删除部门 ID,将自动删除 Employees 表中的对应条目。

在前面的几种情况中,没有任何方法可以将不一致的数据库作为永久数据库提交。SQL Anywhere 还支持在更改造成数据库不一致时使用替代操作。请参见确保数据完整性