Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Italian
  4. Problema con query e QSqlQuery prepare
Forum Updated to NodeBB v4.3 + New Features

Problema con query e QSqlQuery prepare

Scheduled Pinned Locked Moved Solved Italian
23 Posts 2 Posters 8.4k 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.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by
    #2

    Prima di tutto quersto

    QByteArray ba = queryFile.readAll();
    QString strQuery(QString::fromUtf8(ba));
    

    e' un incubo se cambi encoding o modo di scriver il newline. usa:

    QString strQuery = QTextStream(&queryFile).readAll();
    

    Prova a non mettere il ; alla fine e vedi se va

    @fermatqt said in Problema con query e QSqlQuery prepare:

    c'è un modo per visualizzare la query

    http://doc.qt.io/qt-5/qsqlquery.html#lastQuery

    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
    ~Napoleon Bonaparte

    On a crusade to banish setIndexWidget() from the holy land of Qt

    1 Reply Last reply
    0
    • F Offline
      F Offline
      fermatqt
      wrote on last edited by
      #3

      ciao!

      innanzitutto grazie per il suggerimento.
      ho fatto subito la modifica con QTextStream.

      ho levato il ; finale, ma non cmq non ci sono record
      ho messo questa riga:

                 query.exec();
      
                  qDebug() << query.lastQuery(
      

      il problema è che vedo questo:

      "SELECT LT.DESCR128 DESCRIZIONE,LT.NUMERAT || LT.PERIODO || LPAD(LT.NUM, 6, '0') || LT.SERIE LISTINO,MA.CODINT ARTICOLO,LD.PRZDIVISA PREZZO,LD.SCONTO1 SCONTO1,LD.SCONTO2 SCONTO2,LD.SCONTO3 SCONTO3,LT.DAL DAL,LT.AL AL FROM LIST_OFF_DETT LD INNER JOIN MAT_ANAG MA ON MA.NPAM = LD.NPAM INNER JOIN LIST_OFF_TEST LT ON LT.NUMERAT = LD.NUMERAT AND LT.PERIODO = LD.PERIODO AND LT.NUM = LD.NUM AND LT.SERIE = LD.SERIE WHERE MA.DITMAT = 'XXL' AND MA.FVL =  ' ' AND LT.DITTA = 'XXL' AND LT.FVL = ' ' AND LD.DITTA = 'XXL' AND LD.FVL = ' ' AND MA.CODINT = :articolo"
      

      in sostanza non vedo che valore gli arriva!

      1 Reply Last reply
      0
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by
        #4

        per vedere i parametri usa http://doc.qt.io/qt-5/qsqlquery.html#boundValues

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        0
        • F Offline
          F Offline
          fermatqt
          wrote on last edited by
          #5

          ok, allora mi sembra che il parametro arrivi:

           QMapIterator<QString, QVariant> i(query.boundValues());
                      while (i.hasNext()) {
                          i.next();
                          qDebug() << i.key().toUtf8().data() << ": " << i.value().toString().toUtf8().data() << endl;
                      }
          

          ho provato a mettere il parametro fisso così:

          query.bindValue(":articolo", "C165-000");
          

          ma non è cambiato nulla.
          ovviamente se modifico la query in questo modo, funziona:

          SELECT 
          LT.DESCR128 DESCRIZIONE,
          LT.NUMERAT || LT.PERIODO || LPAD(LT.NUM, 6, '0') || LT.SERIE LISTINO,
          MA.CODINT ARTICOLO,
          LD.PRZDIVISA PREZZO,
          LD.SCONTO1 SCONTO1,
          LD.SCONTO2 SCONTO2,
          LD.SCONTO3 SCONTO3,
          LT.DAL DAL,
          LT.AL AL 
          FROM LIST_OFF_DETT LD 
          INNER JOIN MAT_ANAG MA ON MA.NPAM = LD.NPAM 
          INNER JOIN LIST_OFF_TEST LT ON LT.NUMERAT = LD.NUMERAT AND LT.PERIODO = LD.PERIODO AND LT.NUM = LD.NUM AND LT.SERIE = LD.SERIE 
          WHERE 
          MA.DITMAT = 'XXL' AND MA.FVL =  ' ' 
          AND LT.DITTA = 'XXL' AND LT.FVL = ' ' 
          AND LD.DITTA = 'XXL' AND LD.FVL = ' ' 
          AND MA.CODINT = 'C165-000'
          

          quindi si comporta come se non gli arrivasse il parametro in sostanza!

          1 Reply Last reply
          0
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by VRonin
            #6

            dopo che hai eseguito la query senza succasso, puoi chiamare qDebug() << query.lastError().text(); per vedere cosa succede?

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            1 Reply Last reply
            0
            • F Offline
              F Offline
              fermatqt
              wrote on last edited by
              #7

              ciao.

              ho modificato così:

                      if (db->isOpened()) {
                          QFile queryFile(":/get_listini_articolo.txt");
                          queryFile.open(QFile::ReadOnly | QFile::Text);
                          QString strQuery = QTextStream(&queryFile).readAll();
                          strQuery.replace("\n", "");
                          QSqlQuery query;
                          query.prepare(strQuery);
                          query.bindValue(":articolo", "C165-000");
                          query.exec();
              
                          QMapIterator<QString, QVariant> i(query.boundValues());
                          while (i.hasNext()) {
                              i.next();
                              qDebug() << i.key().toUtf8().data() << ": " << i.value().toString().toUtf8().data() << endl;
                          }
              
                          int rows = 0;
                          while (query.next()) {
                              ui->tblArticoli->insertRow(ui->tblArticoli->rowCount());
                              for (int i = 0; i < header.size(); ++i) {
                                  ui->tblArticoli->setItem(rows, i, new QTableWidgetItem(query.value(header.at(i)).toString()));
                              }
                              rows++;
                          }
                          query.clear();
              
                          qDebug() << query.lastError().text();
                      }
              

              come output mi esce questo:

              :articolo :  C165-000 
              
              " "
              

              in sostanza non mostra nessun errore.
              è come se gli arrivasse un parametro "sbagliato" e che non è in grado di leggere bene.
              solo se metto l'uguale nella query, non se metto il LIKE.

              1 Reply Last reply
              0
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #8

                3 cose,

                1. prova a sostituire query.exec(); con if(!query.exec()) Q_ASSERT(false);
                2. che tipo é MA.CODINT? int, nvarchar, etc.
                3. controlla che, con un altro manager per DB riesci a vedere dati con quella query quando usi l'uguale

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  fermatqt
                  wrote on last edited by
                  #9

                  ok, allora:

                  1. ho messo così, me in output non dice nulla; quindi la query dovrebbe essere eseguita:
                          if (db->isOpened()) {
                              QFile queryFile(":/get_listini_articolo.txt");
                              queryFile.open(QFile::ReadOnly | QFile::Text);
                              QString strQuery = QTextStream(&queryFile).readAll();
                              strQuery.replace("\n", "");
                              QSqlQuery query;
                              query.prepare(strQuery);
                              query.bindValue(":articol", "C165-000");
                              //query.exec();
                              if(!query.exec()) Q_ASSERT(false);
                  
                              /*QMapIterator<QString, QVariant> i(query.boundValues());
                              while (i.hasNext()) {
                                  i.next();
                                  qDebug() << i.key().toUtf8().data() << ": " << i.value().toString().toUtf8().data() << endl;
                              }
                              qDebug() << query.lastError().text();*/
                  
                              int rows = 0;
                              while (query.next()) {
                                  ui->tblArticoli->insertRow(ui->tblArticoli->rowCount());
                                  for (int i = 0; i < header.size(); ++i) {
                                      ui->tblArticoli->setItem(rows, i, new QTableWidgetItem(query.value(header.at(i)).toString()));
                                  }
                                  rows++;
                              }
                              query.clear();
                          }
                  
                  1. MA.CODINT è un VARCHAR; il db è ORACLE

                  2. se esguo la query su SQLDEVELOPER funziona correttamente; anzi, io le faccio sempre prima su SQLDEVELOPER in modo da scrivere query corrette ed evitare questi problemi; ed infatti è questo che mi lascia perplesso!

                  VRoninV 1 Reply Last reply
                  0
                  • VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by
                    #10

                    query.bindValue(":articol", "C165-000"); manca una o... typo?

                    Sono abbastanza a corto di idee su cosa possa andare male, l'ultimo tentativo che ti chiederei e' usare positional binding cioe' sostituire :articolo nella query con ? e usare query.bindValue(0, QStringLiteral("C165-000"));

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    1 Reply Last reply
                    0
                    • F Offline
                      F Offline
                      fermatqt
                      wrote on last edited by fermatqt
                      #11

                      articol era solo una prova...

                      cmq ho messo così:

                                  query.bindValue(0, QStringLiteral("C165-000"));
                                  if(!query.exec()) Q_ASSERT(false);
                      
                      

                      e messo il ? nella query.
                      ma non estrae nulla.

                      ti capisco, anche io sono a corto di idee!

                      1 Reply Last reply
                      0
                      • F Offline
                        F Offline
                        fermatqt
                        wrote on last edited by
                        #12

                        allora, ho fatto la prova del 9.
                        ho scritto la query direttamente nel codice e levato il prepare:

                        QString strQuery = "SELECT LT.DESCR128 DESCRIZIONE,LT.NUMERAT || LT.PERIODO || LPAD(LT.NUM, 6, '0') || LT.SERIE LISTINO,MA.CODINT ARTICOLO,LD.PRZDIVISA PREZZO,LD.SCONTO1 SCONTO1,LD.SCONTO2 SCONTO2,LD.SCONTO3 SCONTO3,LT.DAL DAL,LT.AL AL FROM LIST_OFF_DETT LD INNER JOIN MAT_ANAG MA ON MA.NPAM = LD.NPAM INNER JOIN LIST_OFF_TEST LT ON LT.NUMERAT = LD.NUMERAT AND LT.PERIODO = LD.PERIODO AND LT.NUM = LD.NUM AND LT.SERIE = LD.SERIE WHERE MA.DITMAT = 'XXL' AND MA.FVL =  ' ' AND LT.DITTA = 'XXL' AND LT.FVL = ' ' AND LD.DITTA = 'XXL' AND LD.FVL = ' ' AND MA.CODINT = '" + this->articolo + "'";
                        
                                    QSqlQuery query;
                                    query.exec(strQuery);
                        

                        così funziona, concatenando il singolo apice nella stringa del parametro.
                        potrebbe essere quello il problema???

                        1 Reply Last reply
                        0
                        • VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by
                          #13

                          purtroppo quella soluzione apre le porte dell'inferno chiamato SQL Injection quindi non e' accettabile.
                          prova a guardare cosa ti da in output:

                          qDebug() << db->driver->hasFeature(QSqlDriver::PreparedQueries);
                          qDebug() << db->driver->hasFeature(QSqlDriver::NamedPlaceholders);
                          qDebug() << db->driver->hasFeature(QSqlDriver::PositionalPlaceholders);
                          

                          se sono tutti true prova a usare bindValue con la query scritta nel codice e vedere se cosi' funziona

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          1 Reply Last reply
                          0
                          • F Offline
                            F Offline
                            fermatqt
                            wrote on last edited by
                            #14

                            si ma infatti è solo una prova.
                            non ho intenzione di usare la query così!

                            cmq QSqlDriver::NamedPlaceholders mi da false, gli altri true.
                            quindi suppongo debba sempre usare ? e non :articoli.
                            se così, ho provato in questo modo:

                                        QString strQuery = "SELECT LT.DESCR128 DESCRIZIONE,LT.NUMERAT || LT.PERIODO || LPAD(LT.NUM, 6, '0') || LT.SERIE LISTINO,MA.CODINT ARTICOLO,LD.PRZDIVISA PREZZO,LD.SCONTO1 SCONTO1,LD.SCONTO2 SCONTO2,LD.SCONTO3 SCONTO3,LT.DAL DAL,LT.AL AL FROM LIST_OFF_DETT LD INNER JOIN MAT_ANAG MA ON MA.NPAM = LD.NPAM INNER JOIN LIST_OFF_TEST LT ON LT.NUMERAT = LD.NUMERAT AND LT.PERIODO = LD.PERIODO AND LT.NUM = LD.NUM AND LT.SERIE = LD.SERIE WHERE MA.DITMAT = 'XXL' AND MA.FVL =  ' ' AND LT.DITTA = 'XXL' AND LT.FVL = ' ' AND LD.DITTA = 'XXL' AND LD.FVL = ' ' AND MA.CODINT = '?'";
                                        QSqlQuery query;
                                        query.prepare(strQuery);
                                        query.bindValue(0, this->articolo);
                                        query.exec();
                            

                            ma continuo ad avere zero record.

                            1 Reply Last reply
                            0
                            • VRoninV Offline
                              VRoninV Offline
                              VRonin
                              wrote on last edited by
                              #15

                              '?' questo e' sbagliato, non devi mettere gli apostrofi, solo il ?

                              @fermatqt said in Problema con query e QSqlQuery prepare:

                              quindi suppongo debba sempre usare ? e non :articoli.

                              corretto!

                              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                              ~Napoleon Bonaparte

                              On a crusade to banish setIndexWidget() from the holy land of Qt

                              1 Reply Last reply
                              0
                              • F Offline
                                F Offline
                                fermatqt
                                wrote on last edited by
                                #16

                                si quella con '?' era una prova.
                                cmq ho provato sia così:

                                  QString strQuery = ".............. MA.CODINT = ?";
                                            QSqlQuery query;
                                            query.prepare(strQuery);
                                            query.addBindValue("C165-000");
                                

                                che così:

                                  QString strQuery = "........... MA.CODINT = ?";
                                            QSqlQuery query;
                                            query.prepare(strQuery);
                                            query.bindValue(0, this->articolo);
                                

                                non è che debba specificare di che tipo è il bindValue??

                                1 Reply Last reply
                                0
                                • VRoninV Offline
                                  VRoninV Offline
                                  VRonin
                                  wrote on last edited by
                                  #17

                                  no, se this->articolo e' QString il tipo viene dedotto in automatico, devi specificare il tipo solo se vuoi passare l'equivalente di NULL

                                  proviamo con una query base:

                                  QSqlQuery query;
                                  query.prepare("select * from MAT_ANAG where CODINT = ?");
                                  query.bindValue(0, "C165-000");
                                  if(query.exec())
                                  {
                                  while(query.next()){
                                  qDebug() << query.record().value("CODINT");
                                  }
                                  }
                                  else{
                                  qDebug() << query.lastError().text();
                                  }
                                  

                                  e dimmi se ti da risultati

                                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                  ~Napoleon Bonaparte

                                  On a crusade to banish setIndexWidget() from the holy land of Qt

                                  1 Reply Last reply
                                  0
                                  • F Offline
                                    F Offline
                                    fermatqt
                                    wrote on last edited by
                                    #18

                                    ecco il codice:

                                        qDebug() << "STARTED";
                                        if (db->isOpened()) {
                                            QSqlQuery query;
                                            query.prepare("SELECT * FROM MAT_ANAG WHERE CODINT = ?");
                                            query.bindValue(0, "C165-000");
                                            if (query.exec()) {
                                                while (query.next()) {
                                                    qDebug() << "CODINT: " << query.record().value("CODINT");
                                                }
                                            } else {
                                                qDebug() << query.lastError().text();
                                            }
                                        } else {
                                            qDebug() << "DB chiuso";
                                        }
                                        qDebug() << "FINISHED";
                                    

                                    una volta lanciato, il programma lavora per circa 5 secondi.
                                    quindi penso voglia dire che la query la sta eseguendo
                                    ma l'output è solo questo:

                                    STARTED
                                    FINISHED
                                    

                                    inoltre, se scrivessi una query appositamente errata (ad esempio SELEC e non SELECT) vedrei l'errore in console.
                                    quindi anche la query dovrebbe essere giusta.

                                    infine se uso il LIKE funziona:

                                        qDebug() << "STARTED";
                                        if (db->isOpened()) {
                                            QSqlQuery query;
                                            query.prepare("SELECT * FROM MAT_ANAG WHERE CODINT LIKE ?");
                                            query.bindValue(0, "C165-000%");
                                            if (query.exec()) {
                                                while (query.next()) {
                                                    qDebug() << "CODINT: " << query.record().value("CODINT");
                                                }
                                            } else {
                                                qDebug() << query.lastError().text();
                                            }
                                        } else {
                                            qDebug() << "DB chiuso";
                                        }
                                        qDebug() << "FINISHED";
                                    
                                    1 Reply Last reply
                                    0
                                    • VRoninV Offline
                                      VRoninV Offline
                                      VRonin
                                      wrote on last edited by VRonin
                                      #19

                                      a questo punto sono convinto che il problema sia nei dati, non nella query.

                                      Prova una cosa. usa la query con il like ma sostituisci qDebug() << "CODINT: " << query.record().value("CODINT");
                                      con qDebug() << "CODINT: " << query.record().value("CODINT").toString().size(); se stampa 8 mi bevo un'intera bottiglia di vodka in un sol fiato!

                                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                      ~Napoleon Bonaparte

                                      On a crusade to banish setIndexWidget() from the holy land of Qt

                                      1 Reply Last reply
                                      0
                                      • F Offline
                                        F Offline
                                        fermatqt
                                        wrote on last edited by
                                        #20

                                        purtroppo niente vodka, ti avrei fatto volentieri compagni con il gin!

                                        questo il codice:

                                            qDebug() << "STARTED";
                                            if (db->isOpened()) {
                                                QSqlQuery query;
                                                query.prepare("SELECT * FROM MAT_ANAG WHERE CODINT LIKE ?");
                                                query.bindValue(0, "C165-000%");
                                                if (query.exec()) {
                                                    while (query.next()) {
                                                        qDebug() << "CODINT: " << query.record().value("CODINT").toString().size();
                                                    }
                                                } else {
                                                    qDebug() << query.lastError().text();
                                                }
                                            } else {
                                                qDebug() << "DB chiuso";
                                            }
                                            qDebug() << "FINISHED";
                                        

                                        questo l'output:

                                        STARTED
                                        CODINT:  30
                                        CODINT:  30
                                        CODINT:  30
                                        CODINT:  30
                                        ....................
                                        FINISHED
                                        

                                        ho controllato sul db il tipo di campo:
                                        CODINT NOT NULL CHAR(30)

                                        1 Reply Last reply
                                        0
                                        • F fermatqt

                                          ok, allora:

                                          1. ho messo così, me in output non dice nulla; quindi la query dovrebbe essere eseguita:
                                                  if (db->isOpened()) {
                                                      QFile queryFile(":/get_listini_articolo.txt");
                                                      queryFile.open(QFile::ReadOnly | QFile::Text);
                                                      QString strQuery = QTextStream(&queryFile).readAll();
                                                      strQuery.replace("\n", "");
                                                      QSqlQuery query;
                                                      query.prepare(strQuery);
                                                      query.bindValue(":articol", "C165-000");
                                                      //query.exec();
                                                      if(!query.exec()) Q_ASSERT(false);
                                          
                                                      /*QMapIterator<QString, QVariant> i(query.boundValues());
                                                      while (i.hasNext()) {
                                                          i.next();
                                                          qDebug() << i.key().toUtf8().data() << ": " << i.value().toString().toUtf8().data() << endl;
                                                      }
                                                      qDebug() << query.lastError().text();*/
                                          
                                                      int rows = 0;
                                                      while (query.next()) {
                                                          ui->tblArticoli->insertRow(ui->tblArticoli->rowCount());
                                                          for (int i = 0; i < header.size(); ++i) {
                                                              ui->tblArticoli->setItem(rows, i, new QTableWidgetItem(query.value(header.at(i)).toString()));
                                                          }
                                                          rows++;
                                                      }
                                                      query.clear();
                                                  }
                                          
                                          1. MA.CODINT è un VARCHAR; il db è ORACLE

                                          2. se esguo la query su SQLDEVELOPER funziona correttamente; anzi, io le faccio sempre prima su SQLDEVELOPER in modo da scrivere query corrette ed evitare questi problemi; ed infatti è questo che mi lascia perplesso!

                                          VRoninV Offline
                                          VRoninV Offline
                                          VRonin
                                          wrote on last edited by
                                          #21

                                          @fermatqt said in Problema con query e QSqlQuery prepare:

                                          MA.CODINT è un VARCHAR

                                          Mi hai mentito! :)

                                          quindi SELECT TRIM(CODINT) tc FROM MAT_ANAG WHERE tc = ? dovrebbe funzionare

                                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                          ~Napoleon Bonaparte

                                          On a crusade to banish setIndexWidget() from the holy land of Qt

                                          1 Reply Last reply
                                          0

                                          • Login

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