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?

QSqlDatabase SQLite transaction inside of QSqlQuery. How?

Scheduled Pinned Locked Moved Solved General and Desktop
20 Posts 4 Posters 6.8k Views
  • 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.
  • B Offline
    B Offline
    bogong
    wrote on last edited by bogong
    #1

    Hello all!
    Got troubles with executing transactional SQL query in QSqlDatabase with in SQLite.
    The SQL query pretty simple:

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

    When I am using it in plain mode all is OK. When I am using it in transaction:

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

    It's getting failed on preparing it QSqlDatabase::prepare();
    Why it's happening? What am I missing?
    Is there way to use transaction from SQL Query string but not QSqlDatabase::transaction()?

    KroMignonK 1 Reply Last reply
    0
    • B bogong

      Hello all!
      Got troubles with executing transactional SQL query in QSqlDatabase with in SQLite.
      The SQL query pretty simple:

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

      When I am using it in plain mode all is OK. When I am using it in transaction:

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

      It's getting failed on preparing it QSqlDatabase::prepare();
      Why it's happening? What am I missing?
      Is there way to use transaction from SQL Query string but not QSqlDatabase::transaction()?

      KroMignonK Offline
      KroMignonK Offline
      KroMignon
      wrote on last edited by KroMignon
      #2

      @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";
      }
      

      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
      2
      • KroMignonK KroMignon

        @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 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.

        KroMignonK 1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on 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

            @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.

            KroMignonK Offline
            KroMignonK Offline
            KroMignon
            wrote on 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
            2
            • KroMignonK KroMignon

              @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 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.

              KroMignonK 1 Reply Last reply
              0
              • B bogong

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

                KroMignonK Offline
                KroMignonK Offline
                KroMignon
                wrote on 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
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 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
                  • KroMignonK KroMignon

                    @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 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.

                    KroMignonK JonBJ 2 Replies Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 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
                      0
                      • SGaistS SGaist

                        @bogong These are three different requests in one string.

                        B Offline
                        B Offline
                        bogong
                        wrote on 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

                          @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.

                          KroMignonK Offline
                          KroMignonK Offline
                          KroMignon
                          wrote on 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
                          0
                          • B bogong

                            @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.

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on 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
                            • KroMignonK KroMignon

                              @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 last edited by
                              #14

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

                              KroMignonK JonBJ 2 Replies Last reply
                              0
                              • B bogong

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

                                KroMignonK Offline
                                KroMignonK Offline
                                KroMignon
                                wrote on 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
                                0
                                • B bogong

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

                                  JonBJ Offline
                                  JonBJ Offline
                                  JonB
                                  wrote on 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
                                  1
                                  • KroMignonK KroMignon

                                    @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 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.

                                    KroMignonK 1 Reply Last reply
                                    0
                                    • JonBJ JonB

                                      @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 last edited by
                                      #18

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

                                      JonBJ 1 Reply Last reply
                                      0
                                      • B bogong

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

                                        JonBJ Offline
                                        JonBJ Offline
                                        JonB
                                        wrote on 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

                                          @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.

                                          KroMignonK Offline
                                          KroMignonK Offline
                                          KroMignon
                                          wrote on 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

                                          • Login

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