2

新しい QSqlRecord を Postgresql データベースに挿入する際に問題があります。ターゲット テーブルは次のように定義されます。

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 を設定することだけですが、 falsesamochod_idに設定したにもかかわらず、次のメッセージでクラッシュします。isGenerated

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

QSqlRecord の生成をデータベースに残すにはどうすればよいsamochod_idですか?

4

5 に答える 5

2

私はこの問題の奇妙な解決策を見つけました。ライン:

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);
}
于 2012-04-13T21:16:43.957 に答える
2

removeColumn(int)以前に使用できQSqlRecord rec = model->record()、動作するはずです。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、トランザクションで複数のテーブルにレコードを挿入する必要がある場合、複数のをインスタンス化する必要はありません。1つ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
  }
于 2012-04-14T19:19:03.410 に答える
0
于 2012-04-13T20:03:28.183 に答える
0

これは Qt の既知のバグです。Qt 5 で修正されました。

于 2014-02-01T18:55:02.767 に答える
0

これは Qt 4.8 以降の既知のバグです。

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

于 2012-07-10T19:06:19.400 に答える