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

发布于 2024-08-13 23:10:02 字数 732 浏览 9 评论 0原文

我的 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 感到困惑?哦,这与保存的文本大小无关。 多谢。 瓦尔

I am having a strange or maybe not so strange problem with my sqlite db. I have a field of "Text" type and it worked like a charm with any English texts for ages.

The text in the field used to come from an MFC CEdit. Now I switched to CRichEditCtrl to support formatting and UNICODE texts. The CRichEditCtrl dumps the formatted text in hex form like: {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 MS Shell Dlg 2;}} ect.

Once againt the sqlite saves it most of the time just fine. But some time it doesn't giving an error code SQLITE_ERROR /* SQL error or missing database */. the message is not too helpful. the db exists and save most of the time???? Go figure.
Here is the code:

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;
    }

Nothing out of ordinary I think.

Please let me know if you have any ideas. Can it be due to lots of backslashes in the RTF format which somehow confuses sqlite?? Oh, it's not related to size of text saved.
thanks a lot.
Val

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

御守 2024-08-20 23:10:02

该问题肯定是由于代码中没有转义特殊字符造成的。我建议您使用 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()

The problem definitely appears to be due to not escaping special characters in your code. I recommend you use the sqlite API for prepared statements to save yourself from a lot of string processing hassle. They will insert values into queries for you and handle escaping automatically.

Instead of this:

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

You need to do this:

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 will automatically take the value of rtfString, quote it properly, then insert it into the query in place of the question mark.

Another advantage to this way is you can reuse the stmt object. Just call sqlite3_reset() after each use, and remember to call sqlite3_finalize() when you're done for good.

南街女流氓 2024-08-20 23:10:02

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

如果您没有转义引号,那么这可能就是问题所在。假设你首先转义引号,

{blabla\'somethingelse}

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

{blabla\\'somethingelse}

然后瞧,你有一个撇号......

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

If one backslash works, so should several. But it could be that you're not escaping the text correctly, if the text contains an apostrophe or double quote, which would break the query.

If you didn't escape quotes then that may be the problem. Say you do escape quotes first, like

{blabla\'somethingelse}

and then that string is escaped again to preserve the backslashes (otherwise they would be lost in the communication with the database), which would produce

{blabla\\'somethingelse}

and then voila, you have an apostrophe on the loose...

The solution would be to escape backslashes FIRST, then apostrophes and quotes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文