【问题标题】:Subsequent insertion of records with QSqlTableRecord fail after first error第一次错误后使用 QSqlTableRecord 插入记录失败
【发布时间】:2010-07-27 13:16:00
【问题描述】:

我在使用 QSqlTableModel 将数据插入 SQLite 数据库时遇到问题。该表是这样创建的:

QSqlQuery createTblSMS("CREATE TABLE sms_tbl("
        "isRead BOOLEAN NOT NULL,"
        "readTime DATETIME,"
        "arrivalTime DATETIME NOT NULL,"
        "sender TEXT NOT NULL,"
        "receiver TEXT NOT NULL,"
        "smsContent TEXT,"
        "PRIMARY KEY(arrivalTime, sender, receiver));");

我正在插入这样的记录:

smsModel->insertRecord(-1, sms);
QString error = smsModel->lastError().text();
smsModel->submitAll();

smsModel 是 QSqlTableModel。

例如,如果我输入具有此值的记录 (false, NULL, '2010-06-30 17:27:55', '075710383', 'ONE 142140', 'TOP 15 # 2') - 记录被插入。 在该记录之后,如果放置例如具有此值的记录(false,NULL,'2010-06-30 10:05:29','075710383','ONE 142140','TOP 15 #3') - 也是此记录已插入。

但是如果我尝试重新插入已经在数据库,smsModel 将给出这样的错误:“列到达时间,发送者,接收者不是唯一的,无法获取行” - 这是预期的。 任何其他后续插入唯一记录都将失败,并且模型给了我同样的错误。你知道为什么会这样吗?

【问题讨论】:

    标签: c++ qt sqlite qt4


    【解决方案1】:

    我遇到了两个问题。

    当您处于手动提交模式时,QSqlTableModel 在 submitAll 失败时不会清除其缓存(当您向其发送违反约束的记录时它应该这样做)。

    要更正此问题,您需要调用 select() 或 revertAll 来删除那些待处理的更改。

    文档并没有说明这一点,但确实存在,请查看:http://doc.qt.io/qt-4.8/qsqltablemodel.html#submitAll

    【讨论】:

      【解决方案2】:

      过了一会儿,我没能找到 QSqlTableModel 的解决方案,所以我用 QSqlQuery 做了一个解决方法。代码是这样的:

      QSqlQuery query(QSqlDatabase::database(mConnectionName));
          query.prepare("INSERT INTO sms_tbl (isRead, readTime, arrivalTime,"
              "sender, receiver, smsContent) "
              "VALUES (:isRead, :readTime, :arrivalTime, "
              ":sender, :receiver, :smsContent)");
          query.bindValue(":isRead", sms.value("isRead").toBool());
          query.bindValue(":readTime", sms.value("readTime").toString());
          query.bindValue(":arrivalTime", sms.value("arrivalTime").toString());
          query.bindValue(":sender", sms.value("sender").toString());
          query.bindValue(":receiver", sms.value("receiver").toString());
          query.bindValue(":smsContent", sms.value("smsContent").toString());
          query.exec();
      

      【讨论】:

        【解决方案3】:

        您不能再次添加具有相同主键的记录。您有一个主键,其中包含arrivalTime, sender, receiver 列。所以这三个值的值不能相同。

        您可以更改您的 create 语句和 int 类型的 auto increment sms_table_id

        【讨论】:

        • 是的,我知道如果存在具有该主键的记录,我无法添加具有该主键的记录。问题是:尝试添加数据库中已存在的记录后,我无法添加具有唯一主键的记录。
        猜你喜欢
        • 2019-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 2019-01-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多