QSqlRecord在查询中将列的默认值设置为null

时间:2012-04-13 19:45:40

标签: c++ qt postgresql qsqltablemodel

我在将新的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为我设置samochod_id,但是尽管我将isGenerated设置为false,但它会崩溃并显示消息:

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

如何让QSqlRecord将samochod_id生成数据库?

5 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分: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,单个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
  }

答案 2 :(得分:0)

我没有使用过Qt的经验,但我建议您不要为samochod_id列设置任何值。

SQL级别,这可能如下所示:

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

如您所见,我只是“忽略” samochod_id列,让PostgreSQL使用默认值。

答案 3 :(得分:0)

这是自Qt 4.8以来的已知错误:

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

答案 4 :(得分:0)

这是Qt的已知错误。 修正了Qt 5。