2012-04-13 3 views
2

Postgresql 데이터베이스에 새 QSqlRecord를 삽입하는 데 문제가 있습니다.QSqlRecord가 쿼리에서 기본값 null로 열을 설정합니다.

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 열을 효과적으로 숨길 수 있습니다.

이 시도 : 당신은 (수동으로 SQL을 작성하지 않도록) 기록이 방법을 삽입하는 것을 선호하는 이유

// 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); 

내가 이해할 수있다. 레코드를 삽입하기 위해 단지 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 
    } 
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에 대한 알려진 버그입니다. Qt 5에서 수정되었습니다.

관련 문제