我在Qt中有一个数据库。 它有四个表:主组,子组,零件和位置。这是我的数据库:
CREATE TABLE `maingroup` (
`groupName`TEXT NOT NULL UNIQUE,
PRIMARY KEY(`groupName`)
);
CREATE TABLE `subgroup` (
`sub` TEXT NOT NULL UNIQUE,
`main` TEXT NOT NULL,
PRIMARY KEY(`sub`),
FOREIGN KEY(`main`) REFERENCES `maingroup`(`groupName`) ON DELETE CASCADE
);
CREATE TABLE `parts` (
`ID` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
`Part_Number` TEXT,
`Type` TEXT NOT NULL,
`Value` TEXT,
`Voltage` TEXT,
`Quantity` TEXT,
`Position` TEXT,
`Picture` TEXT,
FOREIGN KEY(`Position`) REFERENCES `Position`(`Poistion`) ON DELETE CASCADE,
FOREIGN KEY(`Type`) REFERENCES `subgroup`(`sub`) ON DELETE CASCADE
);
表部件中的类型是外键,是指表子组中的列子。
表子组中的main是外键,指的是表主组中的列组名。
我的问题是,当我在数据库浏览器中尝试(delete from maingroup WHERE groupName= 'dd';
)时,它同时删除了父级和子级。
但是在QT中,此命令(myQuery.exec("delete from maingroup WHERE groupName= 'dd'");
)仅删除主组表中的父字段,而不删除子组和零件表中的子字段,并且子组表中的主列引用主组表中不存在的字段。
这是怎么了?我该怎么办?
答案 0 :(得分:2)
您需要通过在DELETE语句之前执行另一条语句来打开外键编译指示。
QSqlQuery q;
q.exec("PRAGMA foreign_keys = ON");
q.exec("DELETE FROM ...");
这能够级联删除操作,也应该足以解决其他与外键有关的问题。
获得this forum.qt.io帖子的赠送金额。
答案 1 :(得分:0)
除了@TrebledJ正确且非常有用的答案外,值得一提的是有关外键编译指示的两个附加特征(与Qt关联):
1。编译指示也可以通过QSqlDatabase设置。
因此以下代码与@TrebledJ的示例具有相同的作用:
auto database = QSqlDatabase::database();
database.exec("PRAGMA foreign_keys = ON");
QSqlQuery query(database); // query "inherits" the pragma from database
query.exec("DELETE FROM ...");
2。如果在程序中的不同位置打开和使用数据库,甚至会发生这种情况。
效果仍然相同:
初始化代码中的某处: //这会隐式调用database.open(),因为之前未打开数据库。 自动数据库= QSqlDatabase :: database();
QSqlDatabase::database();
database.exec("PRAGMA foreign_keys = ON");
// make sure database.close() is NOT called!
代码中的其他地方
// you'll get the instance of your initialization code because database is already open (so QSqlDatabase::database() implements a singleton pattern).
// so pragma foreign_keys is still set to "ON"
auto database = QSqlDatabase::database();
QSqlQuery query(database);
query.exec("DELETE FROM ...");
了解您是否想知道为什么foreign_keys编译指示似乎有时仅适用于您的项目(有时不适用)的重要性。
我做什么
所以我得出结论,要确保在我的代码中有一个明确的位置可以显式打开数据库(并配置连接):
QString dbConnectionName = "My project database";
auto database = QSqlDatabase::database(dbConnectionName, true);
// configure the pragmas here
在所有其他地方,我避免(偶然地)打开数据库:
auto database = QSqlDatabase::database(dbConnectionName, false);
// e.g. use the database via queries ...