KEY задает ссылку зависимой таблицы на первичный ключ родителя.">
Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗cpSpRlFk 619 of 696 menu
◀ ▶

Внешний ключ SQLite в C++

Ограничение FOREIGN KEY задает ссылку зависимой таблицы на первичный ключ родителя.

В SQLite проверка срабатывает только после PRAGMA foreign_keys = ON на соединении. Таблица складов и ячеек с явной ссылкой на родителя создается так:

#include <iostream> #include <sqlite3.h> int main() { sqlite3* db = nullptr; if (sqlite3_open("fk_bins.db", &db) != SQLITE_OK) { std::cerr << sqlite3_errmsg(db) << "\n"; sqlite3_close(db); return 1; } sqlite3_exec( db, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr ); sqlite3_exec( db, "CREATE TABLE IF NOT EXISTS warehouses (" "id INTEGER PRIMARY KEY, code TEXT NOT NULL)", nullptr, nullptr, nullptr ); sqlite3_exec( db, "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))", nullptr, nullptr, nullptr ); sqlite3_stmt* parent = nullptr; sqlite3_prepare_v2( db, "INSERT INTO warehouses (code) VALUES (?)", -1, &parent, nullptr ); sqlite3_bind_text(parent, 1, "W1", -1, SQLITE_STATIC); sqlite3_step(parent); sqlite3_finalize(parent); sqlite3_stmt* child = nullptr; sqlite3_prepare_v2( db, "INSERT INTO bins (warehouse_id, label) VALUES (?, ?)", -1, &child, nullptr ); sqlite3_bind_int(child, 1, 1); sqlite3_bind_text(child, 2, "A-01", -1, SQLITE_STATIC); sqlite3_step(child); std::cout << sqlite3_changes(db) << "\n"; sqlite3_finalize(child); sqlite3_close(db); return 0; }

Число в warehouse_id должно совпадать с существующим id склада. Иначе шаг вставки вернет код ограничения, а не SQLITE_DONE:

#include <iostream> #include <sqlite3.h> int main() { sqlite3* db = nullptr; if (sqlite3_open("fk_bins.db", &db) != SQLITE_OK) { std::cerr << sqlite3_errmsg(db) << "\n"; sqlite3_close(db); return 1; } sqlite3_exec( db, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr ); sqlite3_exec( db, "CREATE TABLE IF NOT EXISTS warehouses (" "id INTEGER PRIMARY KEY, code TEXT NOT NULL)", nullptr, nullptr, nullptr ); sqlite3_exec( db, "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))", nullptr, nullptr, nullptr ); sqlite3_stmt* bad = nullptr; sqlite3_prepare_v2( db, "INSERT INTO bins (warehouse_id, label) VALUES (?, ?)", -1, &bad, nullptr ); sqlite3_bind_int(bad, 1, 99); sqlite3_bind_text(bad, 2, "ghost", -1, SQLITE_STATIC); int rc = sqlite3_step(bad); if (rc != SQLITE_DONE) { std::cout << "rejected\n"; } sqlite3_finalize(bad); sqlite3_close(db); return 0; }

В fk_bins.db добавьте склад "W2" и ячейку "B-02" с корректным warehouse_id. Выведите число затронутых строк при вставке ячейки через sqlite3_changes.

Попробуйте вставить ячейку с warehouse_id 500. Если шаг вставки не завершился SQLITE_DONE, выведите "bad link".

Создайте в новом файле fk_rooms.db таблицы buildings и rooms со ссылкой на здание. Добавьте здание и комнату с валидным ключом.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить