gpt4 book ai didi

c++ - 如何使用 native sqlite 库而不是 QSql 从 sqlite 插入和检索 QString

转载 作者:搜寻专家 更新时间:2023-10-31 02:24:11 25 4
gpt4 key购买 nike

我在使用 Qt 的 C++ 项目中使用 native sqlite 库(合并 1file),我围绕它创建了一个简单的包装器,但我在插入和选择长 UTF-8 文本时遇到问题。

我使用这段代码来插入数据:

SqlResult *result = new SqlResult();
sqlite3_stmt *statement;
int current_parameter = 1;
this->LastStatement = sql;
int x = sqlite3_prepare_v2(this->db, sql.toUtf8().constData(), sql.length() + 1, &statement, NULL);
foreach (QString text, parameter)
{
////////////// here is problem ///////////////
x = sqlite3_bind_text(statement, current_parameter++, text.toUtf8().constData(), -1, SQLITE_STATIC);
if (!this->Evaluate(x))
...

如您所见,我正在使用 SQL 变量 ?,其中文本使用函数 sqlite3_bind_text(statement, current_parameter++, text.toUtf8().constData(), -1, SQLITE_STATIC) 应该获取 QString 文本的值并将其转换为 utf8 const char *。然而,我在数据库中获得的文本部分是垃圾(当我使用一些 sqlite 浏览器应用程序时,我可以看到一些奇怪的符号)。

这是我用来转换 const char * 的代码,我从 sqlite3_column_text

static QString StringFromUnsignedChar( const unsigned char *str )
{
std::string temp = std::string(reinterpret_cast<const char*>(str));
return QString::fromUtf8(temp.c_str());
}

我得到的文本与我在 sqlite 管理器中看到的相同“垃圾”。所以我想问题出在插入过程中并且选择可能有效。怎么了?我怎样才能正确使用 sqlite3_bind_text 函数和 QString

附言我宁愿不使用 Qt 自己的 sqlite sqlite 实现,主要是出于兼容性目的(在 linux 上我使用 Qt4,在 Windows 上使用 Qt5,我希望到处都有相同的 sqlite 库以实现可移植性)

最佳答案

我的问题出在我自己的代码上,用法正确但实现不正确。这一行:

sqlite3_bind_text(statement, current_parameter++, text.toUtf8().constData(), -1, SQLITE_STATIC);

需要

sqlite3_bind_text(statement, current_parameter++, text.toUtf8().constData(), -1, SQLITE_TRANSIENT);

如文档所述:

The fifth argument to the BLOB and string binding interfaces is a destructor used to dispose of the BLOB or string after SQLite has finished with it. The destructor is called to dispose of the BLOB or string even if the call to bind API fails. If the fifth argument is the special value SQLITE_STATIC, then SQLite assumes that the information is in static, unmanaged space and does not need to be freed. If the fifth argument has the value SQLITE_TRANSIENT, then SQLite makes its own private copy of the data immediately, before the sqlite3_bind_*() routine returns.

因此,使用 QString 和 sqlite 的 native API 的正确方法是:

// Create and evaluate a statement
sqlite3_stmt *statement;
// Note: return value should be checked for error here
sqlite3_prepare_v2(pointer_to_sqlite_db, sql.toUtf8().constData(), sql.length() + 1, &statement, NULL);
// Bind QString to SQL statement - it must be transient so that sql text persist even after function call is over and data is destructed
sqlite3_bind_text(statement, current_parameter++, text.toUtf8().constData(), -1, SQLITE_TRANSIENT);
// step
sqlite3_step(statement);
// clean up
sqlite3_finalize(statement);

如何将 const char * 转换回 QString

static QString StringFromUnsignedChar( const unsigned char *str )
{
return QString::fromUtf8(reinterpret_cast<const char*>(str));
}

QString result = StringFromUnsignedChar(sqlite3_column_text(statement, column));

关于c++ - 如何使用 native sqlite 库而不是 QSql 从 sqlite 插入和检索 QString,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28367049/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com