【发布时间】:2013-11-10 14:47:42
【问题描述】:
以下问题让我很困惑。请记住,我使用的是预编译的 sqlite3.dll,而不是 Qt 的内置 SQLite 支持。
建表代码:
CREATE TABLE STUDY(
Name NOT NULL,
UserName NOT NULL REFERENCES USERS(UserName),
Description DEFAULT NULL,
PathToOsirixDB DEFAULT NULL,
PRIMARY KEY(Name, UserName)
)
如果PathToOsirixDB 列中的值已包含值,则以下 C++ 代码无法更新该值。
它静默失败,不返回任何错误。这意味着 UPDATE 中没有匹配的行。但是,如果我使用 user 和 study 的有效条目进行相同的 UPDATE 以匹配行并通过 SQLite Manager Firefox 插件或命令行工具运行它,它可以正常工作。
void CStudyDatabase::SetOsirixDBForStudy(const QString user, const QString study, const QString path)
{
if (mp_db)
{
int before = sqlite3_total_changes(mp_db);
QString insert = QString("UPDATE STUDY SET PathToOsirixDB = '%1' WHERE Name = '%2' AND UserName = '%3'").arg(path, study, user);
if (!InsertData(insert))
{
int after = sqlite3_total_changes(mp_db);
if (after - before >= 1)
{
SetOsirixDB(path.toAscii().data());
emit ReturnOsirixDB(osirix_db);
}
else
{
emit DatabaseError(QString("Failed to update the target path."));
}
}
}
}
对于插入数据
int CStudyDatabase::InsertData(const QString insert)
{
char *err_msg = 0;
int rc = sqlite3_exec(mp_db,
insert.toStdString().c_str(),
NULL,
this,
&err_msg);
if (rc)
SignalDatabaseError(&err_msg);
return rc;
}
感谢任何见解。谢谢。
更新:将以下代码添加到SetOsiriXDBForStudy 以查看我们是否真的找到要更新的行:
osirix_db = QString("");
QString query = QString("SELECT PathToOsirixDB FROM STUDY WHERE Name = '%1' AND UserName = '%2'").arg(study, user);
int rc = 0;
char *err_msg = 0;
rc = sqlite3_exec(mp_db,
query.toStdString().c_str(),
&OsirixDBCallback,
this,
&err_msg);
if (rc)
SignalDatabaseError(&err_msg);
if (!(QString(osirix_db).isEmpty()))
studyrowfound = true;
在这种情况下,它将 osirix_db 保留为空字符串。
但是,如果我执行这个函数:
void CStudyDatabase::QueryOsirixDB(const QString user, const QString study)
{
int rc = 0;
char *err_msg = 0;
// we query the OrisixDB via the callback and then emit the signal if all went well
QString query = QString("SELECT PathToOsirixDB FROM STUDY WHERE Name = '%1' AND UserName = '%2'").arg(study, user);
rc = sqlite3_exec(mp_db,
query.toStdString().c_str(),
&OsirixDBCallback,
this,
&err_msg);
if (rc)
SignalDatabaseError(&err_msg);
if (QString(osirix_db).isEmpty())
emit NeedToSetOsirixDB(user, study, QString());
else
emit ReturnOsirixDB(osirix_db);
}
然后它确实正确地将预期值检索到 osirix_db 中。
上次更新:发现问题。它是user 和study 上的前导空格。盯着同一个调试器语句太久了,并且掩盖了额外的空间。失败的 SELECT 是一个很大的线索,表明 SQL 的构造有问题。
【问题讨论】:
-
似乎 Qt 与问题无关,因为您不使用 Qt SQL 类。