如何解决带有 FMDB DELETE 的 Swift 忽略外键约束 XCode 12.5
我尝试解决这个问题已经有一段时间了。我正在通过 sqlite3 使用 Swift/SwiftUI 和 FMDB 编写应用程序。当对存在外键的表执行删除时,我希望删除会失败。它没有,也没有抛出错误。
在 XCode 中,我与 libsqlite3.tbd 链接,修改日期为 2021 年 3 月 16 日。在 tbd 文件中,我发现: 安装名称:'/usr/lib/libsqlite3.dylib' 当前版本:321.3 兼容性版本:9
我在以下位置找到 libsqlite3.dylib: /System/Volumes/Data/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib 信息显示它创建于 04/09/2021。没有明显的版本
发生的事情是我在一个名为 BudgetedExpense 的表上有一个名为 BudgetDescription 的表的外键。
BudgetDescription DDL
CREATE TABLE budget_description (
id INTEGER DEFAULT (0)
PRIMARY KEY AUTOINCREMENT
UNIQUE,income_expense_code INTEGER (8) NOT NULL
DEFAULT (0),description STRING NOT NULL
DEFAULT (0),income_or_expense INTEGER NOT NULL
DEFAULT (0)
);
BudgetedExpense DDL
CREATE TABLE budgeted_expense (
expense_id INTEGER NOT NULL
DEFAULT (0)
PRIMARY KEY AUTOINCREMENT
UNIQUE,account_code INTEGER (8) NOT NULL
DEFAULT (0),expense_code INTEGER (8) NOT NULL
DEFAULT (0),budget_year INTEGER (4) NOT NULL
DEFAULT (0),budget_month INTEGER (2) NOT NULL
DEFAULT (0),expense_budget DECIMAL (12,2) NOT NULL
DEFAULT (0),expense_spent DECIMAL (12,unexpected_expense DECIMAL (12,category_code INTEGER (8) NOT NULL
DEFAULT (0),hidden BOOLEAN NOT NULL
DEFAULT (0),hidden_id INTEGER DEFAULT (0),FOREIGN KEY (
account_code,budget_year,budget_month
)
REFERENCES budget (account_code,budget_month),FOREIGN KEY (
expense_code
)
REFERENCES budget_description (income_expense_code) ON DELETE RESTRICT,FOREIGN KEY (
category_code
)
REFERENCES categories (category_code)
);
func updateDatabaseTable(query: String)-> Bool
{
var updateSuccessful: Bool = false
let pragmaQuery = "PRAGMA foreign_keys=ON;"
if openDatabase() {
do {
try database.executeUpdate(pragmaQuery,values: nil)
} catch {
}
queue.inTransaction() {
database,rollback in
do {
try database.executeUpdate(query,values: nil)
updateSuccessful = true
if showQuerys && updateSuccessful {
print("Update query is:\n \(query)")
}
}
catch {
rollback.initialize(to: true)
print(error.localizedDescription)
print(database.lastError())
print(database.lastErrorMessage())
print("UPDATE QUERY Failed")
print(query)
updateSuccessful = false
}
}
_ = closeDatabase()
}
return updateSuccessful
}
执行删除BudgetDescription表中一行的sql是:
// Delete a specific record for a given income/expense code.
func deleteBudgetDescriptionRecordsql(forIncomeExpenseCode incomeExpenseCode: Int) -> String
{
let query =
"""
DELETE FROM \(budget_description_table)
WHERE \(income_expense_code_field) = \(incomeExpenseCode)
"""
return query
}
我写的函数是:
// **** DELETE BUDGET DESCRIPTION RECORD FOR A GIVEN ACCOUNT CODE **** //
func deleteBudgetDescriptionRecord(forIncomeExpenseCode incomeExpenseCode: Int) -> Bool
{
var updateResult: Bool
updateResult = updateBudgetDescriptions(updateQuery: deleteBudgetDescriptionRecordsql(forIncomeExpenseCode: incomeExpenseCode))
if showQuerys {
print("\nQUERY: deleteBudgetDescriptionRecordsql(forIncomeExpenseCode: incomeExpenseCode)")
print(deleteBudgetDescriptionRecordsql(forIncomeExpenseCode: incomeExpenseCode))
}
if updateResult == false {
print("deleteBudgetDescriptionRecordsql returned FALSE when executing QUERY:")
print(deleteBudgetDescriptionRecordsql(forIncomeExpenseCode: incomeExpenseCode))
return updateResult
}
return updateResult
}
执行:
// ********************** PRIVATE DRIVER FUNCTIONS TO EXECUTE DBMANAGER UPDATE DATABASE TABLE METHOD ***********//
private func updateBudgetDescriptions(updateQuery: String) -> Bool
{
var updateResult: Bool
updateResult = DBManager.shared.updateDatabaseTable(query: updateQuery)
return updateResult
}
当我在名为 sqliteStudio 的实用程序中执行此 DELETE sql 时,它失败并显示外键通知。但是当在与 FMDB 相同的数据库上执行时,它执行时没有错误或任何日志通知。
如果在删除时有外键,我在一定程度上依赖于数据库完整性来抛出错误。我已经为此工作了好几天。
我有一个 XCode 项目可以演示这一点,但不知道在哪里或如何上传它以供其他人检查。
如果有任何想法可以帮助我让约束发挥作用,我将不胜感激。
鲍勃
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。