2010-07-27 77 views
1

我有一个问题,插入数据到SQLite数据库使用QSqlTableModel。表创建这样的:后第一个错误后插入记录与QSqlTableRecord失败

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','一个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会给出这样的错误:“列arrivalTime,发件人,接收者不是唯一的无法获取行” - 这是预期的。 任何其他后续插入的唯一记录都将失败,并且该模型会给我提供相同的错误。你有什么线索为什么会发生这种情况?

回答

1

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

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

要纠正这种情况,您需要调用select()或revertAll来删除这些挂起的更改。

的文档不会使这个非常明显的,但它的存在,检查出来:http://doc.qt.io/qt-4.8/qsqltablemodel.html#submitAll

0

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

您可以更改您的创建声明以及类型为intauto incrementsms_table_id

+0

是的,我知道,如果存在记录与该主键,我不能与主键添加记录。 问题是这样的: 我尝试添加数据库中已经存在的记录后,无法添加具有唯一主键的记录。 – user261882 2010-07-28 15:56:09

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();