Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-70362

QSqlQuery.value() with QString type

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P4: Low
    • 6.6.0
    • 5.9.6
    • SQL Support
    • None
    • Win7, Microsoft SQL Server, OBDC
    • Windows
    • efce30bb4 (dev)

    Description

      Hi,

      This is not a major issue but when activating the Trace of my ODBC server and performing query using QSqlQuery with a QString value to get the value of a NVARCHAR field it generates an error in the ODBC Trace log file. But I do get the value.

       

      Here is the cpp code :

      // Code snippet 
      ...
      m_db = QSqlDatabase::database("MyODBCConnectionName");
      QSqlQuery query(m_db);
      if (query.exec("SELECT myText FROM table1"))
      {
          // myText in an NVARCHAR in table1 and table1 isn't empty
          QString val = query.value(0).toString(); //
          // val = "CONTENT_OF_myText"
      }
      ...

      The following lines in SQL.LOG are generated when performing query.value(0).toString() :

      client 2f50-2320	ENTER SQLGetData 
      HSTMT 0x0000000003940CC0
      UWORD 1 
      SWORD -8 <SQL_C_WCHAR>
      PTR 0x0000000000000000 
      SQLLEN 0
      SQLLEN * 0x000000000434E4C8
      
      client 2f50-2320	EXIT SQLGetData with return code -1 (SQL_ERROR)
      HSTMT 0x0000000003940CC0
      UWORD 1 
      SWORD -8 <SQL_C_WCHAR>
      PTR 0x0000000000000000 
      SQLLEN 0
      SQLLEN * 0x000000000434E4C8
      
      DIAG [S1009] [Microsoft][Gestionnaire de pilotes ODBC] Valeur d'argument non valide (0) 
      
      client 2f50-2320	ENTER SQLGetData 
      HSTMT 0x0000000003940CC0
      UWORD 1 
      SWORD -8 <SQL_C_WCHAR>
      PTR 0x000000000434E6B0 
      SQLLEN 92
      SQLLEN * 0x000000000434E4C8
      
      client 2f50-2320	EXIT SQLGetData with return code 0 (SQL_SUCCESS)
      HSTMT 0x0000000003940CC0
      UWORD 1 
      SWORD -8 <SQL_C_WCHAR>
      PTR 0x000000000434E6B0 [ 54] "CONTENT_OF_myText"
      SQLLEN 92
      SQLLEN * 0x000000000434E4C8 (54)

      Looking at some source code here : https://gitlab.com/pteam/pteam-qtbase/blob/latest/src/sql/drivers/odbc/qsql_odbc.cpp 

      It appears that the first call of SQLGetData to get the buffer size in qGetStringData(...) return an error :

      // in src/sql/drivers/odbc/qsql_odbc.cpp
      
      ...
      
      static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool unicode = false)
      {
      QString fieldVal;
      SQLRETURN r = SQL_ERROR;
      SQLLEN lengthIndicator = 0;
      
      // NB! colSize must be a multiple of 2 for unicode enabled DBs
      if (colSize <= 0) {
      colSize = 256;
      } else if (colSize > 65536) { // limit buffer size to 64 KB
      colSize = 65536;
      } else {
      colSize++; // make sure there is room for more than the 0 termination
      }
      if(unicode) {
      r = SQLGetData(hStmt,
      column+1,
      SQL_C_TCHAR,
      NULL,
      0,
      &lengthIndicator);
      if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0)
      colSize = lengthIndicator/sizeof(SQLTCHAR) + 1;
      QVarLengthArray<SQLTCHAR> buf(colSize);
      memset(buf.data(), 0, colSize*sizeof(SQLTCHAR));
      while (true) {
      r = SQLGetData(hStmt,
      column+1,
      SQL_C_TCHAR,
      (SQLPOINTER)buf.data(),
      colSize*sizeof(SQLTCHAR),
      &lengthIndicator);
      if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
      if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) {
      fieldVal.clear();
      break;
      }
      // if SQL_SUCCESS_WITH_INFO is returned, indicating that
      // more data can be fetched, the length indicator does NOT
      // contain the number of bytes returned - it contains the
      // total number of bytes that CAN be fetched
      // colSize-1: remove 0 termination when there is more data to fetch
      int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator/sizeof(SQLTCHAR);
      fieldVal += fromSQLTCHAR(buf, rSize);
      if (lengthIndicator < SQLLEN(colSize*sizeof(SQLTCHAR))) {
      // workaround for Drivermanagers that don't return SQL_NO_DATA
      break;
      }
      } else if (r == SQL_NO_DATA) {
      break;
      } else {
      qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')';
      fieldVal.clear();
      break;
      }
      }
      } else {
      r = SQLGetData(hStmt,
      column+1,
      SQL_C_CHAR,
      NULL,
      0,
      &lengthIndicator);
      if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0)
      colSize = lengthIndicator + 1;
      QVarLengthArray<SQLCHAR> buf(colSize);
      while (true) {
      r = SQLGetData(hStmt,
      column+1,
      SQL_C_CHAR,
      (SQLPOINTER)buf.data(),
      colSize,
      &lengthIndicator);
      if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
      if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) {
      fieldVal.clear();
      break;
      }
      // if SQL_SUCCESS_WITH_INFO is returned, indicating that
      // more data can be fetched, the length indicator does NOT
      // contain the number of bytes returned - it contains the
      // total number of bytes that CAN be fetched
      // colSize-1: remove 0 termination when there is more data to fetch
      int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator;
      fieldVal += QString::fromUtf8((const char *)buf.constData(), rSize);
      if (lengthIndicator < SQLLEN(colSize)) {
      // workaround for Drivermanagers that don't return SQL_NO_DATA
      break;
      }
      } else if (r == SQL_NO_DATA) {
      break;
      } else {
      qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')';
      fieldVal.clear();
      break;
      }
      }
      }
      return fieldVal;
      }
      
      

       

      This is not major as we get the value at the end. But the SQLGetData(...) with NULL and 0 do return an error.

       

      Here is how I actived this Trace log :

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-70362
          # Subject Branch Project Status CR V

          Activity

            People

              mabrand Mark Brand
              paumiern paumiern
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes