SQLite UPDATE 无法覆盖现有值

SQLite UPDATE fails to overwrite existing value

本文关键字:覆盖 UPDATE SQLite      更新时间:2023-10-16

我有以下问题让我感到困惑。 请注意,我使用的是预编译的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 中没有匹配的行。 但是,如果我使用相同的 UPDATE 与 userstudy 的有效条目来匹配一行并通过 SQLite 管理器 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中。

上次更新:发现问题。 它在userstudy上领先空间。 盯着相同的调试器语句太久了,并掩盖了多余的空格。 失败的 SELECT 是一个很大的线索,表明 SQL 的构造存在问题。

用户和学习有领先的空间。盯着相同的调试器语句太久了,并掩盖了多余的空格。失败的 SELECT 是一个很大的线索,表明 SQL 的构造存在问题。