第一次错误后,QSqlTableRecord后续插入记录失败

时间:2010-07-27 13:16:00

标签: c++ qt sqlite qt4

使用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。

如果我举例说明这个值的记录(假,NULL,'2010-06-30 17:27:55','075710383','ONE 142140','TOP 15#2') - 记录插入。 在该记录之后,如果举例来说这个值(假,NULL,'2010-06-30 10:05:29','075710383','ONE 142140','TOP 15#3') - 也是这个记录插入。

但是如果我尝试重新插入记录(false,NULL,'2010-06-30 17:27:55','075710383','ONE 142140','TOP 15#2')已经在数据库,smsModel将给出如下错误:“columns arrivalTime,sender,receiver不是唯一的无法获取行” - 这是预期的。 任何其他后续插入的唯一记录都将失败,并且模型会给我相同的错误。你有什么想法发生这种情况吗?

3 个答案:

答案 0 :(得分:1)

我遇到了这个两折的问题。

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

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

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

答案 1 :(得分:0)

您无法再次添加具有相同主键的记录。您有主键,其中包含arrivalTime, sender, receiver列。因此,您不能使用这三个值具有相同值的值。

您可以更改您的创建语句以及sms_table_id类型的auto increment int

答案 2 :(得分:0)

过了一段时间我没有找到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();