2012-04-13 177 views
2

我有一個插入新的QSqlRecord到Postgresql數據庫的問題。目標表的定義如下:QSqlRecord將默認值列設置爲空查詢

create table samochod(
    samochod_id integer primary key default nextval('samochod_id_seq'), 
    marka varchar(30), 
    poj_silnika numeric, 
    typ_silnika silnik_typ, 
    liczba_osob smallint 
); 

和記錄插入的代碼是:

QSqlRecord rec = model->record(); 

    rec.setGenerated("samochod_id", false); 
    rec.setValue("marka", ui.brandEdit->text()); 
    rec.setValue("poj_silnika", ui.volSpin->value()); 
    rec.setValue("typ_silnika", ui.engineCombo->currentText()); 
    rec.setValue("liczba_osob", ui.passengersSpin->value()); 

    bool ok = model->insertRecord(-1,rec); 

所有我想要做的是插入一個新的記錄,使得SQL爲我設置其samochod_id,但儘管我設置isGenerated將其與消息崩潰錯誤:

"ERROR: null value in column "samochod_id" violates not-null constraint 
QPSQL: Unable to create query" 

我應該怎麼做才能讓QSqlRecord離開一代samochod_id數據庫?

回答

1

可以QSqlRecord rec = model->record()之前使用removeColumn(int)它應該工作。如果model與視圖(例如QTableView實例)相關聯,則您將實際隱藏samochod_id列。

試試這個:

// get the index of the id column 
    int colId = model.fieldIndex("samochod_id"); 
    // remove the column from the model 
    model.removeColumn(colId); 

    QSqlRecord rec = model->record(); 

    // rec.setGenerated("samochod_id", false); /// not needed anymore 
    rec.setValue("marka", ui.brandEdit->text()); 
    rec.setValue("poj_silnika", ui.volSpin->value()); 
    rec.setValue("typ_silnika", ui.engineCombo->currentText()); 
    rec.setValue("liczba_osob", ui.passengersSpin->value()); 

    bool ok = model->insertRecord(-1,rec); 

我能理解你爲什麼喜歡插入記錄這種方式(避免手工編寫SQL)。 我認爲使用QSqlTableModel僅用於插入記錄的實例太昂貴(模型是複雜的野獸),所以我更喜歡使用普通的QSqlQuery。通過這種方法,沒有必要,如果你需要插入多個表中的記錄在一個事務中來實例化多個QSqlTableModel S,單QSqlQuery是不夠的:

QSqlDatabase::database("defaultdb").transaction(); 
    QSqlQuery query(QSqlDatabase::database("defaultdb")); 

    query.prepare(QString("INSERT INTO table1 (field1, field2) VALUES(?,?)")); 
    query.bindValue(0,aString); 
    query.bindValue(1,anotherString); 
    query.exec(); 

    // insert in another table 
    query.exec(QString("INSERT INTO table2 (field1, field2) VALUES(...)"); 

    bool ok = QSqlDatabase::database("defaultdb").commit(); 
    query.finish(); 

    if(!ok){ 
     // do something 
    } 
0

我沒有使用Qt的經驗,但我建議設置samochod_id列沒有任何值。

SQL水平,這可能是這樣的:

INSERT INTO samochod (marka, poj_silnika, poj_silnika, liczba_osob) 
    VALUES (...); 

正如你看到的,我只是「忽略」samochod_id列,讓PostgreSQL的使用默認值。

+0

如果我不使用Qt的SQL類,它會爲我生成查詢,我會按照您的說法完成它。我的問題是如何讓他們做我想做的事,而不是如何自己動手做。 – KCH 2012-04-13 20:07:32

+0

你可以註釋掉'rec.setGenerated(「samochod_id」,false);'看看它是怎麼回事? – vyegorov 2012-04-13 20:09:47

+0

這很奇怪,但它不會改變應用程序行爲。文檔說,留下這條線未註釋應使數據庫爲我生成此字段。 – KCH 2012-04-13 20:12:17

1

我發現了這個問題的一個奇怪的解決方案。行:以上

rec.setGenerated("samochod_id", false); 

INT方法似乎沒有任何影響,但是當我把它的信號我的模型的處理程序,它開始按預期方式工作:

CarsModel::CarsModel(QObject * parent, QSqlDatabase db) 
    : SqlModel(parent, db, "samochod") 
{ 
    engineTypes << "Diesel" << "Na gaz" << "Benzynowy" << "Elektryczny"; 

    connect(this, SIGNAL(beforeInsert(QSqlRecord &)), this, 
     SLOT(beforeInsertRec(QSqlRecord &))); 
} 


void CarsModel::beforeInsertRec(QSqlRecord & rec){ 
    rec.setGenerated(0, false); 
} 
0

這是Qt的一個已知的bug。 在Qt 5中已修復。