2012-04-13 3 views
2

にnullにデフォルト値を持つ列を設定します。次のようにターゲット表が定義されています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を設定しますが、にも関わらず、私はそれがメッセージでクラッシュfalseに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を使用することを好むと思います。

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

見ての通り、私はちょうどPostgreSQLがデフォルト値を使用せ、samochod_id列を「無視」。

+0

で修正された 私は私のためのクエリを生成するQtのSQLクラスを、使用しなかった場合、あなたが言うように、私はまさにそれを行っているでしょう。私の質問は、自分自身で手作業で行う方法ではなく、自分が望むようにする方法でした。 – KCH

+0

'rec.setGenerated(" samochod_id "、false);'をコメントアウトして、それがどうなるか見てみることができますか? – vyegorov

+0

奇妙ですが、アプリケーションの動作は変わりません。ドキュメントでは、この行のコメントを外しておくと、データベースがこのフィールドを私に生成させるはずです。 – KCH

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の4.8以降の既知のバグです:

このアプローチでは、あなたがトランザクション内で複数のテーブルにレコードを挿入する必要がある場合、単一 QSqlQueryが十分にある複数の QSqlTableModel Sをインスタンス化する必要はありません

https://bugreports.qt-project.org/browse/QTBUG-23592

0

これはQtのに既知のバグです。 Qtの5

関連する問題