Внешний ключ SQLite в Dart
Ограничение FOREIGN KEY привязывает колонку
зависимой таблицы к первичному ключу родителя.
В SQLite проверка срабатывает только после
PRAGMA foreign_keys = ON на соединении -
этот вызов нужно выполнить один раз сразу после
открытия базы, прежде чем вставлять связанные
строки.
Таблица складов и ячеек с явной ссылкой на родителя создается так:
import 'package:sqlite3/sqlite3.dart';
var db = sqlite3.open('fk_bins.db');
db.execute('PRAGMA foreign_keys = ON');
db.execute('''
CREATE TABLE IF NOT EXISTS warehouses (
id INTEGER PRIMARY KEY,
code TEXT NOT NULL
)
''');
db.execute('''
CREATE TABLE IF NOT EXISTS bins (
id INTEGER PRIMARY KEY,
warehouse_id INTEGER NOT NULL,
label TEXT NOT NULL,
FOREIGN KEY (warehouse_id)
REFERENCES warehouses (id)
)
''');
db.execute(
'INSERT INTO warehouses (code) VALUES (?)',
['W1'],
);
db.execute(
'INSERT INTO bins (warehouse_id, label) VALUES (?, ?)',
[1, 'A-01'],
);
print(db.updatedRows);
db.dispose();
Число в warehouse_id должно совпадать с
существующим id склада. Иначе вставка
останавливает программу с ошибкой:
import 'package:sqlite3/sqlite3.dart';
var db = sqlite3.open('fk_bins.db');
db.execute('PRAGMA foreign_keys = ON');
db.execute('''
CREATE TABLE IF NOT EXISTS warehouses (
id INTEGER PRIMARY KEY,
code TEXT NOT NULL
)
''');
db.execute('''
CREATE TABLE IF NOT EXISTS bins (
id INTEGER PRIMARY KEY,
warehouse_id INTEGER NOT NULL,
label TEXT NOT NULL,
FOREIGN KEY (warehouse_id)
REFERENCES warehouses (id)
)
''');
try {
db.execute(
'INSERT INTO bins (warehouse_id, label) VALUES (?, ?)',
[99, 'ghost'],
);
} catch (e) {
print('rejected');
}
db.dispose();
В fk_bins.db добавьте склад "W2"
и ячейку "B-02" с корректным
warehouse_id. Выведите число затронутых
строк при вставке ячейки.
Попробуйте вставить ячейку с warehouse_id
500 в try. При ошибке выведите
"bad link".
Создайте в новом файле fk_rooms.db
таблицы buildings и rooms со
ссылкой на здание. Добавьте здание и комнату с
валидным ключом.