我在将新的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
生成数据库?
答案 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以来的已知错误:
答案 4 :(得分:0)
这是Qt的已知错误。 修正了Qt 5。