问题描述
我尝试解决这个问题已经有一段时间了。我正在通过 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 (将#修改为@)