Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QSqlDatabase SQLite transaction inside of QSqlQuery. How?
Forum Updated to NodeBB v4.3 + New Features

QSqlDatabase SQLite transaction inside of QSqlQuery. How?

Scheduled Pinned Locked Moved Solved General and Desktop
20 Posts 4 Posters 7.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K KroMignon
    15 Dec 2019, 12:50

    @bogong Hi using transaction with SQLite is easy:

    auto db = QSqlDatabase::database("my connection name");
    
    if(db.transaction())
    {
        QSqlQuery query(db);
        // do stuff
    
       if(!db.commit())
       {
            qDebug() << "Failed to commit";
            db.rollback();
       }
    }
    else
    {
        qDebug() << "Failed to start transaction mode";
    }
    
    B Offline
    B Offline
    bogong
    wrote on 15 Dec 2019, 13:31 last edited by
    #3

    @KroMignon Thx for rapid reply. I know it perfectly. The question is about how to use SQLite native transactional mechanism, there is where I've got troubles.

    K 1 Reply Last reply 15 Dec 2019, 13:39
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 15 Dec 2019, 13:36 last edited by
      #4

      Hi,

      begin/endTransaction are using SQLite's native mechanism.

      If you want to do it by hand, then you have to make two additional queries, one for BEGIN before your other query and then one for COMMIT.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • B bogong
        15 Dec 2019, 13:31

        @KroMignon Thx for rapid reply. I know it perfectly. The question is about how to use SQLite native transactional mechanism, there is where I've got troubles.

        K Offline
        K Offline
        KroMignon
        wrote on 15 Dec 2019, 13:39 last edited by
        #5

        @bogong But this does it... calling QSqlDatabase::transaction() will insert the SQL sentence "BEGIN TRANSACTION;" and QSqlDatabase::commit() will insert the SQL sentence "COMMIT;".

        If you want to use a QSqlQuery with transaction, you should do it like I show it to you in my small code extract.
        What is the problem with using QSqlDatabase::transaction()/QSqlDatabase::commit()?

        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

        B 1 Reply Last reply 15 Dec 2019, 13:40
        2
        • K KroMignon
          15 Dec 2019, 13:39

          @bogong But this does it... calling QSqlDatabase::transaction() will insert the SQL sentence "BEGIN TRANSACTION;" and QSqlDatabase::commit() will insert the SQL sentence "COMMIT;".

          If you want to use a QSqlQuery with transaction, you should do it like I show it to you in my small code extract.
          What is the problem with using QSqlDatabase::transaction()/QSqlDatabase::commit()?

          B Offline
          B Offline
          bogong
          wrote on 15 Dec 2019, 13:40 last edited by
          #6

          @KroMignon The question is about how to use SQLite native transactional mechanism. I need to be able to execute any SQL String.

          K 1 Reply Last reply 15 Dec 2019, 13:42
          0
          • B bogong
            15 Dec 2019, 13:40

            @KroMignon The question is about how to use SQLite native transactional mechanism. I need to be able to execute any SQL String.

            K Offline
            K Offline
            KroMignon
            wrote on 15 Dec 2019, 13:42 last edited by KroMignon
            #7

            @bogong But you can execute any SQL string you want, this will do exactly what you show as example:

            auto db = QSqlDatabase::database("my connection name");
            
            if(db.transaction())
            {
                QSqlQuery query(db);
                // do stuff
                query.execute("INSERT INTO log (value1,value2,value3) VALUES (1,2,3);");
            
               if(!db.commit())
               {
                    qDebug() << "Failed to commit";
                    db.rollback();
               }
            }
            else
            {
                qDebug() <<  "Failed to start transaction mode";
            }
            

            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

            B 1 Reply Last reply 15 Dec 2019, 13:43
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 15 Dec 2019, 13:43 last edited by
              #8

              @bogong said in QSqlDatabase SQLite transaction inside of QSqlQuery. How?:

              @KroMignon The question is about how to use SQLite native transactional mechanism. I need to be able to execute any SQL String.

              @bogong that's what both @KroMignon and I are trying to make you understand. Under the hood, the SQLite backend uses native SQLite to start and end the transaction.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • K KroMignon
                15 Dec 2019, 13:42

                @bogong But you can execute any SQL string you want, this will do exactly what you show as example:

                auto db = QSqlDatabase::database("my connection name");
                
                if(db.transaction())
                {
                    QSqlQuery query(db);
                    // do stuff
                    query.execute("INSERT INTO log (value1,value2,value3) VALUES (1,2,3);");
                
                   if(!db.commit())
                   {
                        qDebug() << "Failed to commit";
                        db.rollback();
                   }
                }
                else
                {
                    qDebug() <<  "Failed to start transaction mode";
                }
                
                B Offline
                B Offline
                bogong
                wrote on 15 Dec 2019, 13:43 last edited by bogong
                #9

                @KroMignon Again - the question is about how to use SQLite native transactional mechanism. It's mean string should be

                BEGIN TRANSACTION;
                INSERT INTO log (value1,value2,value3) VALUES (1,2,3);
                COMMIT;
                

                And it's not working.

                K J 2 Replies Last reply 15 Dec 2019, 13:49
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 15 Dec 2019, 13:44 last edited by
                  #10

                  @bogong These are three different requests in one string.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  B 1 Reply Last reply 15 Dec 2019, 13:47
                  0
                  • S SGaist
                    15 Dec 2019, 13:44

                    @bogong These are three different requests in one string.

                    B Offline
                    B Offline
                    bogong
                    wrote on 15 Dec 2019, 13:47 last edited by bogong
                    #11

                    @SGaist The canonical SQL approach is ONE string that might be containing HUGE amount of requests. And I am trying to execute ONE string that might be containing any amount of requests. And It's not working in QT. When I am using it in directly in SQLite all is ok.

                    1 Reply Last reply
                    0
                    • B bogong
                      15 Dec 2019, 13:43

                      @KroMignon Again - the question is about how to use SQLite native transactional mechanism. It's mean string should be

                      BEGIN TRANSACTION;
                      INSERT INTO log (value1,value2,value3) VALUES (1,2,3);
                      COMMIT;
                      

                      And it's not working.

                      K Offline
                      K Offline
                      KroMignon
                      wrote on 15 Dec 2019, 13:49 last edited by
                      #12

                      @bogong said in QSqlDatabase SQLite transaction inside of QSqlQuery. How?:

                      the question is about how to use SQLite native transactional mechanism.

                      I don't know how to explain it in another way:
                      You cannot do more than 1 SQL sentence in a QSqlQuery, so if you want to do transaction with SQLite DB and Qt, you have to use QSqlDatabase::transaction()/QSqlDatabase::commit() like I show you in my short example.

                      Of course you can insert as many QSqlQuery between QSqlDatabase::transaction()/QSqlDatabase::commit().

                      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                      B 1 Reply Last reply 15 Dec 2019, 13:50
                      0
                      • B bogong
                        15 Dec 2019, 13:43

                        @KroMignon Again - the question is about how to use SQLite native transactional mechanism. It's mean string should be

                        BEGIN TRANSACTION;
                        INSERT INTO log (value1,value2,value3) VALUES (1,2,3);
                        COMMIT;
                        

                        And it's not working.

                        J Offline
                        J Offline
                        JonB
                        wrote on 15 Dec 2019, 13:49 last edited by
                        #13

                        @bogong
                        Both @KroMignon & @SGaist are right.

                        Your only chance of single-line-multi-statement with SQLite will be to drop your parameter binding. Try:

                        BEGIN TRANSACTION; INSERT INTO log (value1,value2,value3) VALUES (1,2,3); COMMIT;
                        

                        Oh, I think you are saying you have tried that (without binding parameters) and it still does not work? I think you have to execute sqlite3_exec() to get multi-statement, if Qt isn't going through that with no parameter binding then it looks like it's tricky....

                        1 Reply Last reply
                        0
                        • K KroMignon
                          15 Dec 2019, 13:49

                          @bogong said in QSqlDatabase SQLite transaction inside of QSqlQuery. How?:

                          the question is about how to use SQLite native transactional mechanism.

                          I don't know how to explain it in another way:
                          You cannot do more than 1 SQL sentence in a QSqlQuery, so if you want to do transaction with SQLite DB and Qt, you have to use QSqlDatabase::transaction()/QSqlDatabase::commit() like I show you in my short example.

                          Of course you can insert as many QSqlQuery between QSqlDatabase::transaction()/QSqlDatabase::commit().

                          B Offline
                          B Offline
                          bogong
                          wrote on 15 Dec 2019, 13:50 last edited by
                          #14

                          @KroMignon Again - one string mean BEGIN and COMMIT is in string too. And it's not working in QT.

                          K J 2 Replies Last reply 15 Dec 2019, 13:54
                          0
                          • B bogong
                            15 Dec 2019, 13:50

                            @KroMignon Again - one string mean BEGIN and COMMIT is in string too. And it's not working in QT.

                            K Offline
                            K Offline
                            KroMignon
                            wrote on 15 Dec 2019, 13:54 last edited by KroMignon
                            #15

                            @bogong said in QSqlDatabase SQLite transaction inside of QSqlQuery. How?:

                            Again - one string mean BEGIN and COMMIT is in string too. And it's not working in QT.

                            no this can not work because the are 3 SQL sentences:

                            1. BEGIN TRANSACTION;
                            2. INSERT ...
                            3. COMMIT;

                            and you can only have 1 SQL sentence in a QSqlQuery::execute().

                            Is this clear enough to you?

                            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                            B 1 Reply Last reply 15 Dec 2019, 13:59
                            0
                            • B bogong
                              15 Dec 2019, 13:50

                              @KroMignon Again - one string mean BEGIN and COMMIT is in string too. And it's not working in QT.

                              J Offline
                              J Offline
                              JonB
                              wrote on 15 Dec 2019, 13:56 last edited by JonB
                              #16

                              @bogong
                              I have answered your question above, up to you whether you take heed or not (though it's always nice not to be ignored).

                              If you wish to pursue from Qt, take a look at https://code.woboq.org/qt5/qtbase/src/3rdparty/sqlite/sqlite3.c.html. If you search for sqlite3_exec() you'll come across

                              ** CAPI3REF: One-Step Query Execution Interface
                              ** METHOD: sqlite3
                              **
                              ** The sqlite3_exec() interface is a convenience wrapper around
                              ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
                              ** that allows an application to run multiple statements of SQL
                              ** without having to use a lot of C code.
                              ...
                              */
                              SQLITE_API int sqlite3_exec(
                                sqlite3*,                                  /* An open database */
                                const char *sql,                           /* SQL to be evaluated */
                                int (*callback)(void*,int,char**,char**),  /* Callback function */
                                void *,                                    /* 1st argument to callback */
                                char **errmsg                              /* Error msg written here */
                              );
                              
                              
                              B 1 Reply Last reply 15 Dec 2019, 14:00
                              1
                              • K KroMignon
                                15 Dec 2019, 13:54

                                @bogong said in QSqlDatabase SQLite transaction inside of QSqlQuery. How?:

                                Again - one string mean BEGIN and COMMIT is in string too. And it's not working in QT.

                                no this can not work because the are 3 SQL sentences:

                                1. BEGIN TRANSACTION;
                                2. INSERT ...
                                3. COMMIT;

                                and you can only have 1 SQL sentence in a QSqlQuery::execute().

                                Is this clear enough to you?

                                B Offline
                                B Offline
                                bogong
                                wrote on 15 Dec 2019, 13:59 last edited by bogong
                                #17

                                @KroMignon This clear for me since 2014. And I've been writting it in second message that replied to you. I've been talking about all in ONE string like in SQL Specification. ONE STRING mean - it should be executed if there canonical syntax. BEGIN and COMMIT - canonical syntax and it's not working in QT. And again - I DO NOT asking about how to use Qt Transaction mechanism, I know it perfectly. I am asking how to use SQLite native mechanism in QT when I can only execute string. This two points have huge difference.

                                K 1 Reply Last reply 15 Dec 2019, 18:15
                                0
                                • J JonB
                                  15 Dec 2019, 13:56

                                  @bogong
                                  I have answered your question above, up to you whether you take heed or not (though it's always nice not to be ignored).

                                  If you wish to pursue from Qt, take a look at https://code.woboq.org/qt5/qtbase/src/3rdparty/sqlite/sqlite3.c.html. If you search for sqlite3_exec() you'll come across

                                  ** CAPI3REF: One-Step Query Execution Interface
                                  ** METHOD: sqlite3
                                  **
                                  ** The sqlite3_exec() interface is a convenience wrapper around
                                  ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
                                  ** that allows an application to run multiple statements of SQL
                                  ** without having to use a lot of C code.
                                  ...
                                  */
                                  SQLITE_API int sqlite3_exec(
                                    sqlite3*,                                  /* An open database */
                                    const char *sql,                           /* SQL to be evaluated */
                                    int (*callback)(void*,int,char**,char**),  /* Callback function */
                                    void *,                                    /* 1st argument to callback */
                                    char **errmsg                              /* Error msg written here */
                                  );
                                  
                                  
                                  B Offline
                                  B Offline
                                  bogong
                                  wrote on 15 Dec 2019, 14:00 last edited by
                                  #18

                                  @JonB Thx. Will try to do it. But been trying to avoid plan C. looks like will not.

                                  J 1 Reply Last reply 15 Dec 2019, 14:26
                                  0
                                  • B bogong
                                    15 Dec 2019, 14:00

                                    @JonB Thx. Will try to do it. But been trying to avoid plan C. looks like will not.

                                    J Offline
                                    J Offline
                                    JonB
                                    wrote on 15 Dec 2019, 14:26 last edited by
                                    #19

                                    @bogong
                                    It is only my understanding. But I believe you will have to go via something like that sqlite3 code interface in order to execute multi-statements at a time, which probably corresponds to your "When I am using it in directly in SQLite all is ok." finding. I think that from Qt, QSqlQuery is only going to execute a single statement for SQLite.

                                    1 Reply Last reply
                                    0
                                    • B bogong
                                      15 Dec 2019, 13:59

                                      @KroMignon This clear for me since 2014. And I've been writting it in second message that replied to you. I've been talking about all in ONE string like in SQL Specification. ONE STRING mean - it should be executed if there canonical syntax. BEGIN and COMMIT - canonical syntax and it's not working in QT. And again - I DO NOT asking about how to use Qt Transaction mechanism, I know it perfectly. I am asking how to use SQLite native mechanism in QT when I can only execute string. This two points have huge difference.

                                      K Offline
                                      K Offline
                                      KroMignon
                                      wrote on 15 Dec 2019, 18:15 last edited by
                                      #20

                                      @bogong said in QSqlDatabase SQLite transaction inside of QSqlQuery. How?:

                                      I am asking how to use SQLite native mechanism in QT when I can only execute string. This two points have huge difference.

                                      Nope, there is no difference: using QSqlDatabase::transaction() / commit() is the Qt "sugar" to use SQLite "native mechanism" (or other Database type like mySQL for example).

                                      There are 2 ways to do it:

                                      • use Qt way (QSqlDatabase + QSqlQuery)
                                      • do it your own way, for example by calling "sqlite" executable from command line.

                                      Try to mixup booth is a very bad idea.
                                      A basic rule I always try to follow is: when I try to work against the framework, then there something I am doing wrong or misusing.

                                      Just for my personal curiosity, why do you not want to use QSqlDatabase::transation()/commit()?

                                      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                      1 Reply Last reply
                                      1

                                      12/20

                                      15 Dec 2019, 13:49

                                      • Login

                                      • Login or register to search.
                                      12 out of 20
                                      • First post
                                        12/20
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved