最近使用 SQLite 做开发,发现 SQLite 的外键是默认关闭的,必须在每次操作数据库的时候打开,这给我造成了不小的困扰,据官方文档说,做成这样是因为 SQLite 默认不支持外键约束,加入之后为了避免兼容性问题做了一个开关,并且默认是关闭的。但是对于我们来说,完全没有必要考虑兼容性的问题,所以我就想能不能自己编译一个 SQLite, 使其默认开启外键约束?
在官方网站上,我找到了 SQLite 3 的源码(sqlite-amalgamation-3260000,3.26.0 下载地址:SQLite-326 ),集合版本,所有的源代码都集成在一个 C 文件中,有22万多行,7.4MiB。
经过一番查找,我发现了控制外键 FLAG (可设置的属性)中的一段宏
#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
| SQLITE_ForeignKeys
#endif
这里判断是否定义了 SQLITE_DEFAULT_FOREIGN_KEYS 这个宏,以此判断是否在 FLAG 中加入 SQLITE_ForeignKeys 的控制项,简单粗暴起见,可以直接将其定义为1,这样这个字段永远为真,就可以了。
在官方文档中还说了,Foreign key 必须在 SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER 均未定义的情况下才起作用,所以我们将宏定义放在此间:
/************** Begin file fkey.c ********************************************/
/*
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used by the compiler to add foreign key
** support to compiled SQL statements.
*/
/* #include "sqliteInt.h" */
#ifndef SQLITE_OMIT_FOREIGN_KEY
#ifndef SQLITE_OMIT_TRIGGER
// 新增了下面这一句
#define SQLITE_DEFAULT_FOREIGN_KEYS 1
// ...
然后执行
./configure; make
进行编译(官方文档中有说明),生成的 sqlite3.exe 即为默认支持外键的版本,并且在其中执行
PRAGMA foreign_keys; 输出默认为1,默认添加不符合外键约束的列时也会报错。