2010-07-27 79 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();