2012-04-13 178 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中已修复。