- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我在使用 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/
我正在使用 Qt5 访问 MySQL 数据库。使用 QSqlQuery + prepare() + bindValue() 很容易执行 INSERT 查询。 现在我注意到 bindValue() 有一
如何从“数据库”向表“test”插入二进制数据,其中包含 2 列文本“name”和 bin“pic” QSqlDatabase db = QSqlDatabase::addDatabase("QPSQ
我最近开始发现需要从 __mysql 模块更改为 PyQt 的 QSql,但不知道从哪里开始。我想做的(现在)就是从数据库中读取并打印结果。这是我得到的最远的,但我不断收到从 query.exec_(
我正在尝试将数据插入表中。这是代码: void AddContacts::saveContact() { QString first_name = ui->lineFirstName->tex
我想将一些值插入到 SQLite 表中。 查询是: insert into TableName (field1,field2,field3) values (field1val, field2val,
出于某些(好吧,性能)原因,Qt 的“模型”类仅从数据库中获取 256 行,因此如果您想将该行追加到记录集的末尾,显然,您必须按照以下方式做一些事情 while (model->canFetchMor
我想生成一个足够简单的应用程序,它使用 QTreeView 小部件来显示 SQLite3(平面)表中的分层数据,使用 QDataWidgetMapper 填充一些行编辑字段,允许用户编辑,从而更新表。
我在使用 Qt 的 C++ 项目中使用 native sqlite 库(合并 1file),我围绕它创建了一个简单的包装器,但我在插入和选择长 UTF-8 文本时遇到问题。 我使用这段代码来插入数据:
考虑以下与 postgres 数据库的交互: QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL"); db.setHostName("acidali
我是一名优秀的程序员,十分优秀!