Verzweifelt mit GetFieldValue und CDBVariant



  • Hallo Community,

    ich habe über ODBC eine Anbindung an vorher nicht bekannte Datenbanken (access, mssql-server, ...)

    ich selektiere daraus eine definierte Tabelle über "SELECT * FROM tabelle" in ein CRecordset

    Nun durchlaufe ich die einzelnen Spalten des Ergebnisses und möchte abhängig von dem Datentyp den Wert auslesen und ggfls noch modifizieren.

    Mit GetFielValue() kann ich das Feld auslesen, und in dem befüllten CDBVariant sollte ja auch der Typ richtig zugeordnet werden. So dachte ich zumindest.
    Unter Access scheint das auch ganz gut geklappt zu haben aber auf einem MSSQL-Server lief er immer in DBVT_NULL rein, obwohl es ein "varchar" oder "decimal" war.

    Wie komme ich an die Ergebniswerte?

    Vielen Dank
    Smeagol

    PS: ich hab zur Nachvollziehbarkeit mal den source angehängt, das Rekordset wird in XML umgewandelt.

    try {
        CRecordset rs;
        CString sql= "SELECT * FROM " + table + " WHERE " + krit;
    
        rs.m_pDatabase = &m_db;
        rs.Open(CRecordset::forwardOnly, sql, CRecordset::readOnly);
    
        // Werte ermitteln
        while(!rs.IsEOF()) {
          // Für jeden Datensatz einen neuen Vorgang
          CXmlEle* xmlvrg = xml.NewEle("VORGANG");
          CODBCFieldInfo fieldinfo;
          CDBVariant variant;
          short f;
          for(f=0; f < rs.GetODBCFieldCount(); ++f)
          {
            rs.GetODBCFieldInfo(f, fieldinfo);
            rs.GetFieldValue(f, variant);
            switch(variant.m_dwType) {
              case DBVT_NULL:
                // nix tun   <- warum läuft der SQL-Server fast immer hier rein???
                break;
              case DBVT_DOUBLE:
                xmlvrg->AddDbl(fieldinfo.m_strName, variant.m_dblVal);
                break;
              case DBVT_BOOL:
                xmlvrg->AddInt(fieldinfo.m_strName, variant.m_boolVal);
                break;
              case DBVT_UCHAR:
                xmlvrg->AddText(fieldinfo.m_strName, (char*)&variant.m_chVal);
                break;
              case DBVT_SHORT:
                xmlvrg->AddInt(fieldinfo.m_strName, variant.m_iVal);
                break;
              case DBVT_LONG:
                xmlvrg->AddInt(fieldinfo.m_strName, variant.m_lVal);
                break;
              case DBVT_SINGLE:
                xmlvrg->AddDbl(fieldinfo.m_strName, variant.m_fltVal);
                break;
              case DBVT_STRING:
                xmlvrg->AddText(fieldinfo.m_strName, *variant.m_pstring);
                break;
              case DBVT_DATE:
                xmlvrg->AddText(fieldinfo.m_strName, ToString((long)variant.m_pdate->day) + "." + ToString((long)variant.m_pdate->month) + "." + ToString((long)variant.m_pdate->year));
                break;
              case DBVT_BINARY:
                {
                CString bindata((LPTSTR)GlobalLock(variant.m_pbinary->m_hData));
                GlobalUnlock(variant.m_pbinary->m_hData);
                xmlvrg->AddText(fieldinfo.m_strName, bindata);
                }
                break;
            }
          }
    
          rs.MoveNext();
        }
    
        rs.Close();
      }
      catch(CDBException *e) 
      {
        Trace(e->m_strError);
        err = IDS_STRUCTURE_WRONG;
        e->Delete();
      }
    


  • Warum nimmst Du nicht m_nSQLType aus der Struktur CODBCFieldInfo? Dort sollte doch der richtige Type angegeben sein. Nur mal so als Gedanke.

    Gruß Matthias



  • Sicher könnte man darüber nachdenken, aber trotzdem ist der Variant ja leer.
    ich könnte dann GetFieldValue über die CString-alternative lesen und die Daten konvertieren, aber vom Gefühl her klingt das eher wie ein Würg-around.

    Fällt nicht jemand noch eine Alternative ein, bzw. hat eine Erklärung für diese Phänomen?

    Danke Euch!

    Smeagol


Anmelden zum Antworten