外键未被执行

20

为什么下面的外键约束(虽然可以正常执行),但SQLite没有强制执行?我该如何强制执行这种关系?

CREATE TABLE User (
    UserID TEXT Unique NOT NULL PRIMARY KEY,
    FirstName TEXT NOT NULL,
    LastName TEXT NOT NULL,
    Username TEXT NOT NULL,
    Password TEXT NOT NULL,
    Email TEXT NOT NULL,
    SignupDate TEXT NOT NULL
)

CREATE TABLE Category (
    CategoryID TEXT Unique NOT NULL PRIMARY KEY,
    UserID TEXT,
    FOREIGN KEY(UserID) REFERENCES User(UserID)
)
2个回答

30

正如相关文档所述(在2.启用外键支持一节中):

假设编译库已启用外键约束,则应用程序仍必须在运行时使用PRAGMA foreign_keys命令启用它。例如:

sqlite> PRAGMA foreign_keys = ON;

默认情况下禁用外键约束(出于向后兼容性的考虑),因此必须单独为每个数据库连接启用。

在相关连接中是否使用了PRAGMA呢?(当然,假设文档所述的SQLite已适当编译并且是足够新的版本以提供外键约束执行功能)。


1
非常感谢您的及时回复。我从未在文档中注意到这一点(下次会更加仔细)。刚刚尝试运行该命令时,我收到了以下错误:“SQLite prepare() failed. ERROR: authorization denied DETAILS: not authorized EXPRESSION: PRAGMA foreign_keys = ON;”我猜测他们使用的版本可能不支持它或已禁用该功能。如果可以的话,我能否使用触发器创建相同的结果?如果可以,请问有人可以提供SQLITE的示例触发器语法吗? - Maxim Gershkovich
@Maxim,我认为sqlite外键触发器需要与普通的外键完全相同的基本功能(通常在希望尽可能小而快速地提供“完整关系ACID能力”的嵌入式构建中删除)以获得实质性的性能和占用空间的成本。 - Alex Martelli

6

您也可以通过嵌入连接字符串来启用外键支持:

foreign keys=True

例子:

"Data Source={DatabaseFullFilePath};Version=3;foreign keys=True;datetimeformat=CurrentCulture"

读者注意:这是针对ODBC连接字符串的,而不是针对sqlite自己的uri文件名。截至2022年,sqlite不支持通过uri文件名直接启用FKs。 - Masklinn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接