SQLITE更新失败,错误代码为1(SQLITE_ERROR)

时间:2009-12-11 21:08:49

标签: sqlite unicode rtf

我的sqlite数据库有一个奇怪的或者可能不那么奇怪的问题。我有一个“文本”类型的字段,它的作用就像任何英文文本的魅力一样。

以前的字段中的文本来自MFC CEdit。现在我切换到CRichEditCtrl以支持格式化和UNICODE文本。 CRichEditCtrl以十六进制形式转储格式化文本,如:{\ rtf1 \ ansi \ ansicpg1252 \ deff0 \ deflang1033 {\ fonttbl {\ f0 \ fnil \ fcharset0 MS Shell Dlg 2;}}等。

再一次,sqlite大部分时间都可以保存它。但有一段时间它没有给出错误代码SQLITE_ERROR / * SQL错误或缺少数据库* /。这条消息不太有帮助。数据库存在并保存大部分时间????去搞清楚。 这是代码:

error = sqlite3_exec(db,cmd,0,0,0);
if (error != SQLITE_OK){
    errMsg.Format("Unable to save notes to: %s\nSQLite Error: %d",filename,error);
    AfxMessageBox(_T(errMsg));
    sqlite3_close(db);
    return false;
    }

我认为没有什么不寻常的。

如果您有任何想法,请告诉我。可能是由于RTF格式中的大量反斜杠,它会以某种方式混淆sqlite?哦,它与保存的文本大小无关。 非常感谢。 瓦尔

2 个答案:

答案 0 :(得分:2)

问题肯定是因为你的代码中没有转义特殊字符。我建议您使用sqlite API来准备语句,以避免大量的字符串处理麻烦。他们会为您插入值并自动处理转义。

而不是:

error = sqlite3_exec(db,cmd,0,0,0);

你需要这样做:

sqlite3_stmt *stmt;
error = sqlite3_prepare_v2(database, "INSERT INTO table (field) VALUES (?)", -1, &stmt, NULL);
if (error != SQLITE_OK) { ...
error = sqlite3_bind_text(stmt, 1, rtfString, -1, SQLITE_STATIC);
if (error != SQLITE_OK) { ...
error = sqlite3_step(stmt);
if (error != SQLITE_DONE) { ...
sqlite3_finalize(stmt);

sqlite将自动获取rtfString的值,正确引用,然后将其插入查询中代替问号。

这种方式的另一个好处是可以重用stmt对象。每次使用后只需致电sqlite3_reset(),并记得在完成任务后致电sqlite3_finalize()

答案 1 :(得分:1)

如果一个反斜杠有效,那么应该有几个。但是,如果文本包含撇号或双引号,则可能无法正确转义文本,这会破坏查询。

如果你没有逃避报价,那么这可能就是问题所在。假设你先做引号,比如

{blabla\'somethingelse}

然后再次转义该字符串以保留反斜杠(否则它们将在与数据库的通信中丢失),这将产生

{blabla\\'somethingelse}

然后瞧,你松散的撇号......

解决方案是首先转义反斜杠,然后是撇号和引号。