Results 1 to 10 of 10

Thread: PostgreSQL and QT4 automate id problem!

  1. #1
    Join Date
    Oct 2006
    Posts
    13
    Thanks
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default PostgreSQL and QT4 automate id problem!

    I am having problem with my database application. I am using a postgreSQL and QT4. I have created a connection in the main.cpp and it works fine.
    There are other forms too, but none of them is using an inline function to automaticaly generate the id number to some of the tables.

    Here is the structure of the table:

    CREATE TABLE "Blood"
    (
    "GroupID" int4 NOT NULL,
    "Group" varchar(3),
    CONSTRAINT "Blood_pkey" PRIMARY KEY ("GroupID")
    )
    WITHOUT OIDS;
    ALTER TABLE "Blood" OWNER TO postgres;

    Here are the functions I use to insert a new data in the table:


    Qt Code:
    1. inline int generateId(const QString &table)
    2. {
    3. QSqlQuery query;
    4. query.exec(" SELECT MAX(GroupID) FROM " + table);
    5. if (!query.isActive())
    6. cerr << "Error" << endl;
    7. int id = 0;
    8. if (query.next())
    9. id = query.value(0).toInt() + 1;
    10. return id;
    11.  
    12. }
    13.  
    14. void Krv::AddRec()
    15. {
    16. int row = model->rowCount();
    17. model->insertRow(row);
    18. QModelIndex index = model->index(row, Group);
    19. tableView->setCurrentIndex(index);
    20. tableView->edit(index);
    21. }
    22.  
    23. void Krv::beforeInsertRec(QSqlRecord &record)
    24. {
    25. record.setValue("GroupID", generateId(table));
    26. }
    To copy to clipboard, switch view to plain text mode 

    I am constantly getting an error message as the query is not active.
    I can delete from the same form, I can insert a first record, but the id wont iterate.
    It always got the id=0 value? Can someone help???
    Last edited by wysota; 25th December 2006 at 10:49. Reason: missing [code] tags

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: PostgreSQL and QT4 automate id problem!

    The ID should get autogenerated by the database if you pass NULL to it as the primary key value. You shouldn't try to generate the id yourself. Imagine there are two concurrent inserts into the database - manual fetching of the maximum id present in the database doesn't guarantee that something else doesn't use that id in between the time when you do the check and when you actually insert the record. You'd have to use transactions to make sure of that, but this slows up the mechanism significantly (locking the row or making a snapshot of the table, then rolling back the transaction if it fails and repeating the process again and again), so you should avoid such methods as well and rely on internal database mechanisms for generating primary keys. You just have to set up the table correctly so that it knows how to generate keys (for example you can use a trigger for that).

    As for the error itself, I suggest you use QSqlError::text() to peek for the nature of the error in the query.

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: PostgreSQL and QT4 automate id problem!

    Quote Originally Posted by nnidza View Post
    CREATE TABLE "Blood"
    (
    "GroupID" int4 NOT NULL,
    ...
    )
    WITHOUT OIDS;
    ALTER TABLE "Blood" OWNER TO postgres;
    Try:
    SQL Code:
    1. CREATE TABLE "Blood"
    2. (
    3. "GroupID" serial NOT NULL,
    4. ...
    5. )
    6. ...
    To copy to clipboard, switch view to plain text mode 
    and:
    Qt Code:
    1. void Krv::beforeInsertRec(QSqlRecord &record)
    2. {
    3. record.setGenerated( "GroupID", false );
    4. }
    To copy to clipboard, switch view to plain text mode 
    This way PostgreSQL will use a sequence to generate GroupIDs in a safe manner.
    It always got the id=0 value? Can someone help???
    The problem is that you probably don't submit changes to the database, so every time you call generateId() is operates on an empty table, but first make sure that the query is correct.

    See QSqlTableModel::setEditStrategy().

  4. #4
    Join Date
    Jan 2006
    Location
    Lincoln, NE USA
    Posts
    177
    Thanks
    3
    Thanked 7 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: PostgreSQL and QT4 automate id problem!

    Qt Code:
    1. CREATE TABLE employee
    2. (
    3. empid int8 NOT NULL DEFAULT nextval('employee_empid_seq'::regclass),
    4. empname varchar(30) NOT NULL,
    5. revid varchar(10),
    6. passwd varchar(15) NOT NULL DEFAULT 'unknown'::character varying,
    7. ....
    8. }
    To copy to clipboard, switch view to plain text mode 
    and to generate the empid field value automatically:
    Qt Code:
    1. CREATE SEQUENCE employee_empid_seq
    2. INCREMENT 1
    3. MINVALUE 1
    4. MAXVALUE 9223372036854775807
    5. START 1361
    6. CACHE 1;
    To copy to clipboard, switch view to plain text mode 
    When you insert a row into the table don't include the id field, it will be supplied automatically by the sequence.

  5. #5
    Join Date
    Oct 2006
    Posts
    13
    Thanks
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: PostgreSQL and QT4 automate id problem!

    Ok, it works now.
    Wysota thank you for your advice, I'll keep that on my mind when I make some more complex forms...
    I didn't understand your solution Jacek. What is serial exactly? A new data type? Sorry I am not so familiar with PostgreSQL.
    GreyGeek you solution works! I don't need any transactions now as I am under the PostgreSQL protections? Am I right?

    And some of you mentioned trigers. No clue so far... Is it a complex explanation to drop a few lines before I read a tutorial?

    Marry Christmas to all of you that celebrates...

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: PostgreSQL and QT4 automate id problem!

    Quote Originally Posted by nnidza View Post
    And some of you mentioned trigers. No clue so far... Is it a complex explanation to drop a few lines before I read a tutorial?
    http://en.wikipedia.org/wiki/Database_trigger

    Marry Christmas to all of you that celebrates...
    Thanks

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: PostgreSQL and QT4 automate id problem!

    Quote Originally Posted by nnidza View Post
    I didn't understand your solution Jacek. What is serial exactly? A new data type?
    Yes, it's a special data type. It's an equivalent of GreyGeek's solution, only shorter.

    http://www.postgresql.org/docs/8.2/s...ATATYPE-SERIAL

  8. #8
    Join Date
    Jan 2006
    Location
    Lincoln, NE USA
    Posts
    177
    Thanks
    3
    Thanked 7 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: PostgreSQL and QT4 automate id problem!

    Quote Originally Posted by jacek View Post
    Yes, it's a special data type. It's an equivalent of GreyGeek's solution, only shorter.

    http://www.postgresql.org/docs/8.2/s...ATATYPE-SERIAL
    Last week I upgraded from PostgreSQL 8.1.4 to 8.2 on my W2K workstation. My compiles stopped with an error while attempting to load a dll.

    qsqlpsql.dll loaded ssleay32.dll which loaded leay32.dll which failed because the first dll was looking for functions which weren't present on one of the secure shell dlls. Dependencychecker showed the problem, but I am at home and don't have access to my notes. But, basically, when Qt attempts to load a library and it fails, it is marked so that it won't load again until the library is recompiled, or at least touched, so that the timestamp changes. Then Qt will attempt to load it again.

    When I reverted back to 8.1.4 Qt4.2.2 apps compiled OK.

  9. #9
    Join Date
    Jan 2006
    Location
    Lincoln, NE USA
    Posts
    177
    Thanks
    3
    Thanked 7 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: PostgreSQL and QT4 automate id problem!

    Quote Originally Posted by nnidza View Post
    I don't need any transactions now as I am under the PostgreSQL protections? Am I right?
    No. You still may need to use transactions.

    A classic example is the General Journal posting. Say you have a table containing daily postings of debits and credits to various accounts. You want to post those amounts to their specific debit and credit accounts to that your accounts remain balanced. If any of them fail you want to revert all of them. You do that by
    Begin;
    post the daily transactions to the general ledger
    Commit;
    (or Rollback if things didn't go well).
    See http://www.postgresql.org/docs/8.1/i...nsactions.html

    This avoids the "dirty read" problem:
    http://www.informit.com/articles/art...&seqNum=6&rl=1

  10. #10
    Join Date
    Jan 2006
    Location
    Lincoln, NE USA
    Posts
    177
    Thanks
    3
    Thanked 7 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: PostgreSQL and QT4 automate id problem!

    Triggers are very useful. Their use is only limited by your imagination.

    A simple use is backing up changes made by clerks. A trigger on the UPDATE would save the *.NEW or *.OLD record in a history table automatically. Then, if a question arises as to who changed what and when you can consult the history table. If you need to revert a change you can use the history table as the source of the previous record.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.