我用CCommand<CDynamicAccessor> command 命令查询数据库
通过command.GetValue()获取各个列的数据,但通过各种转换方法都无法得出正确的数值,不知道有什么好的方法,我在网上查了一些例子,但总是转换不到正确的数据,请高手帮忙???
愿付高分,先给100!!!!!!!!!!!!!!!1付例子:CStrinbg sSQLCmd = _T("SELECT * FROM HISDATA20070711 WHERE TAGTIME > '2007-7-11 14:06:35'");
CCommand<CDynamicAccessor> rs; 
HRESULT hr = rs.Open(Session,sSQLCmd,NULL,NULL,DBGUID_DBSQL,FALSE);
CDBPropSet propset(DBPROPSET_ROWSET);
propset.AddProperty(DBPROP_CANFETCHBACKWARDS,true);     
propset.AddProperty(DBPROP_IRowsetChange,true);   
propset.AddProperty(DBPROP_UPDATABILITY,DBPROPVAL_UP_CHANGE|DBPROPVAL_UP_INSERT|DBPROPVAL_UP_DELETE);   HRESULT hr = rs.Open(m_Session,sSQLCmd,&propset);
int nCount =0;
DBSTATUS dbStatus;    
DBTYPE dbType;    
CString str;    
double dValue; 
long lValue;   
VARIANT vt;
  

while(SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET )
{
    for(size_t nCol=1; nCol< rs.GetColumnCount();nCol++)
    {
rs.GetStatus(nCol, &dbStatus);
if(dbStatus != DBSTATUS_S_ISNULL && rs.GetColumnType(nCol, &dbType)) 
{
  switch (dbType)
  {     
    case DBTYPE_WSTR:        
    case DBTYPE_BSTR:     str = (LPCWSTR)rs.GetValue(nCol); break;   
    case DBTYPE_I1:       
    case DBTYPE_UI1:      lValue = (long)(*((BYTE*)rs.GetValue(nCol)));     break; 
    case DBTYPE_I2:        
    case DBTYPE_UI2:      lValue = (long)(*((short*)rs.GetValue(nCol)));    break;   
    case DBTYPE_I4:       
    case DBTYPE_UI4:      lValue = (long)(*((long*)rs.GetValue(nCol)));     break; 
    case DBTYPE_R4:       dValue = (double)(*((float*)rs.GetValue(nCol)));  break;  
    case DBTYPE_R8:       dValue = *((double*)rs.GetValue(nCol));           break;
            default:
             break;           }
      }
}
}

解决方案 »

  1.   

    是不是要“日期值以“#”(数字记号)分界(如“start_date > #7/22/97#”)”?
      

  2.   

    楼主的rs.GetValue的参数是不是有问题。
    下面是CDynamicAccessor的GetValue原型和说明。
    //////////////////////////////////
     
    void* GetValue( 
       DBORDINAL nColumn  
    ) const throw( );
    void* GetValue(
       const CHAR* pColumnName 
    ) const throw( );
    void* GetValue(
       const WCHAR* pColumnName 
    ) const throw( );
    template < class ctype >
    bool GetValue(
       DBORDINAL nColumn,
       ctype* pData 
    ) const throw( );
    template < class ctype >
    bool GetValue(
       const CHAR* pColumnName,
       ctype* pData 
    ) const throw( );
    template < class ctype >
    bool GetValue(
       const WCHAR* pColumnName,
       ctype* pData 
    ) const throw( );
     
    Parameters
    ctype 
    [in] A templated parameter that handles any data type except string types (CHAR*, WCHAR*), which require special handling. GetValue uses the appropriate data type based on what you specify here.nColumn 
    [in] The column number. Column numbers start with 1. A value of 0 refers to the book column, if any.pColumnName 
    [in] The column name.pData 
    [out] The pointer to the contents of the specified column
      

  3.   

    我在MSDN查到的CDynamicAccessor有以下几个重载函数
    void* GetValue( ULONG nColumn ) const;void* GetValue( TCHAR* pColumnName ) const;template < class ctype >
    bool GetValue( ULONG nColumn, ctype* pData ) const;template < class ctype >
    bool GetValue( TCHAR *pColumnName, ctype* pData ) const;好多例子都是直接用的第一个函数。
      

  4.   

    如果用模版函数,那么各种数据类型怎么对应ctype呢?
      

  5.   

    是我搞错了,其实是一样的,DBORDINAL被定义为ULONG。
    ////////////////////////////////////////////////////
    但是你这部分是错的。
     case DBTYPE_I1:       
        case DBTYPE_UI1:      lValue = (long)(*((BYTE*)rs.GetValue(nCol)));     break; 
        case DBTYPE_I2:        
        case DBTYPE_UI2:      lValue = (long)(*((short*)rs.GetValue(nCol)));    break;   
        case DBTYPE_I4:       
        case DBTYPE_UI4:      lValue = (long)(*((long*)rs.GetValue(nCol)));     break; 
        case DBTYPE_R4:       dValue = (double)(*((float*)rs.GetValue(nCol)));  break;  
        case DBTYPE_R8:       dValue = *((double*)rs.GetValue(nCol));           
    /////////////////////////////
    除了string data,rs.GetValue(nCol);返回的是字符串指针,其它的类型都返回true或false
    你应该这样调用
    LONG pDate;
    rs.GetValue(nCol,&pDate);
    ///////////////////////////////////////
    Return Value
    If you want to pass string data, use the nontemplated versions of GetValue. The nontemplated versions of this method return void*, which points to the part of the buffer that contains the specified column data. Returns NULL if the column is not found.For all other data types, it is simpler to use the templated versions of GetValue. The templated versions return true on success or false on failure.
      

  6.   

    //改成如下
    while(SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET )
    {
        for(size_t nCol=1; nCol< rs.GetColumnCount();nCol++)
        {
    rs.GetStatus(nCol, &dbStatus);
    if(dbStatus != DBSTATUS_S_ISNULL && rs.GetColumnType(nCol, &dbType)) 
    {
      switch (dbType)
      {     
        case DBTYPE_WSTR:        
        case DBTYPE_BSTR:     str = (LPCWSTR)rs.GetValue(nCol); break;   
        case DBTYPE_I1:       
        case DBTYPE_UI1:     rs.GetValue(nCol,&lValue);     
    break; 
        case DBTYPE_I2:        
        case DBTYPE_UI2:     rs.GetValue(nCol,&lValue); 
      break;  
                 case DBTYPE_R4:       rs.GetValue(nCol,&dValue); 
     break; 
        case DBTYPE_R8:       rs.GetValue(nCol,&dValue);           break;
                default:
                 break;           }
          }
    }
    }
      

  7.   

    感谢楼上,但我按照您的修改后,还是无法得到数据。况且还出现了ATLASSERT错误!!
      

  8.   

    况且用str=(LPCWSTR)rs.GetValue(nCol),的到的str为空值。
      

  9.   

    字符串类型的:
    _variant_t vt;
    vt = rs.GetValue(nCol);
    vt.ChangeType(VT_BSTR);//看情况,有时不转换也行
    str=(LPCTSTR)vt.bstrVal;其它类型的看类_variant_t
      

  10.   

    试试这样:
    case DBTYPE_BSTR:     str = *(BSTR*)rs.GetValue(nCol);break;