第一次错误后使用 QSqlTableRecord 插入记录失败

Posted

技术标签:

【中文标题】第一次错误后使用 QSqlTableRecord 插入记录失败【英文标题】:Subsequent insertion of records with QSqlTableRecord fail after first error 【发布时间】: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 将给出这样的错误:“列到达时间,发送者,接收者不是唯一的,无法获取行” - 这是预期的。 任何其他后续插入唯一记录都将失败,并且模型给了我同样的错误。你知道为什么会这样吗?

【问题讨论】:

【参考方案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

【讨论】:

是的,我知道如果存在具有该主键的记录,我无法添加具有该主键的记录。问题是:尝试添加数据库中已存在的记录后,我无法添加具有唯一主键的记录。

以上是关于第一次错误后使用 QSqlTableRecord 插入记录失败的主要内容,如果未能解决你的问题,请参考以下文章

我正在尝试使用 c++ STL 制作 prims 算法。在迭代器第一次迭代后,它会停止代码并给出错误的输出

第一次检测到错误后返回错误代码

PFLogInViewController 错误-使用 Parse 注销后无法登录 Facebook

pod 安装后 Alamofire 出现错误

为啥在第一次 Fetch 后出现字段计数不匹配错误?

通过 Heroku 托管 Discord Bot,在尝试以前的建议后重复 EADDRINUSE 错误