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
    #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
                                      • F Offline
                                        F Offline
                                        fermatqt
                                        wrote on last edited by
                                        #22

                                        scusa ero sicuro che fosse un VARCHAR!!
                                        ma più che altro su mysql non mi sembra di riscontrare questo comportamento che ho su oracle (ma magari mi sbaglio).

                                        cmq col TRIM funziona.

                                        grazie mille, ti devo una bottiglia di vodka!!

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

                                          Nessun problem, felice che si sia risolto

                                          "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