MFC CRecodeSet类的难题我想写一个动态绑定变量及字段的CRecodeSet的继承类为什么使用静态绑定时,程序可以通过而使用动态绑定时,却有"数据被截断的错误",请问哪个数据库的高手,有此方面的经验,切磋切磋.哪个知道原因的啊?如果修改呢?
------------------------------------------------
为什么每次问数据库的问题,回答的人总是不多呢?

解决方案 »

  1.   

    静态绑定列//cpp文件
    CTestODBCSet::CTestODBCSet(CDatabase* pdb)
    : CRecordset(pdb)
    {
    //{{AFX_FIELD_INIT(CTestODBCSet)
    m_PartID = 0;
    m_PartName = _T("");
    m_PartThickness = _T("");
    m_PartMaterial = _T("");
    m_PartNum = 0;
    m_PartRemain = 0;
    m_BlockID = 0;
    m_Deleted = FALSE;
    m_CreateDate = _T("");
    m_CreateTime = _T("");
    m_CreateID = _T("");
    m_ModifyDate = _T("");
    m_ModifyTime = _T("");
    m_ModifyID = _T("");
    m_nFields = 15;
    //}}AFX_FIELD_INIT
    m_nDefaultType = snapshot;
    }void CTestODBCSet::DoFieldExchange(CFieldExchange* pFX)
    {
    //{{AFX_FIELD_MAP(CTestODBCSet)
    pFX->SetFieldType(CFieldExchange::outputColumn);
    RFX_Long(pFX, _T("PartID"), m_PartID);
    RFX_Text(pFX, _T("PartName"), m_PartName);
    RFX_Text(pFX, _T("[PartThickness]"), m_PartThickness);
    RFX_Text(pFX, _T("[PartMaterial]"), m_PartMaterial);
    RFX_Int(pFX, _T("[PartNum]"), m_PartNum);
    RFX_Int(pFX, _T("[PartRemain]"), m_PartRemain);
    RFX_LongBinary(pFX, _T("[PartData]"),m_PartData);
    RFX_Long(pFX, _T("[BlockID]"), m_BlockID);
    RFX_Bool(pFX, _T("[Deleted]"), m_Deleted);
    RFX_Text(pFX, _T("[CreateDate]"), m_CreateDate);
    RFX_Text(pFX, _T("[CreateTime]"), m_CreateTime);
    RFX_Text(pFX, _T("[CreateID]"), m_CreateID);
    RFX_Text(pFX, _T("[ModifyDate]"), m_ModifyDate);
    RFX_Text(pFX, _T("[ModifyTime]"), m_ModifyTime);
    RFX_Text(pFX, _T("[ModifyID]"), m_ModifyID);
    //}}AFX_FIELD_MAP
    }//h文件---变量定义
    long m_PartID;
    CString m_PartName;
    CString m_PartThickness;
    CString m_PartMaterial;
    int m_PartNum;
    int m_PartRemain;
    CLongBinary m_PartData;
    long m_BlockID;
    BOOL m_Deleted;
    CString m_CreateDate;
    CString m_CreateTime;
    CString m_CreateID;
    CString m_ModifyDate;
    CString m_ModifyTime;
    CString m_ModifyID;
      

  2.   

    修改成使用指针的方式来绑定列
    CTestODBCSet::CTestODBCSet(CDatabase* pdb)
    : CRecordset(pdb)
    {
    this->m_PartID = new long;
    m_PartName     = new CString;
    m_PartThickness = new CString;
    m_PartMaterial  = new CString;
    m_PartNum       = new int;
    m_PartRemain    = new int; m_BlockID       = new long;
    m_Deleted       = new int; m_PartData      = new CLongBinary;         m_CreateDate    = new CString;
    m_CreateTime    = new CString;
    m_CreateID      = new CString;
    m_ModifyDate    = new CString;
    m_ModifyTime    = new CString;
    m_ModifyID      = new CString; //{{AFX_FIELD_INIT(CTestODBCSet)
    *m_PartID = 0;
    *m_PartName = _T("");
    *m_PartThickness = _T("");
    *m_PartMaterial = _T("");
    *m_PartNum = 0;
    *m_PartRemain = 0;
    *m_BlockID = 0;
    *m_Deleted = FALSE;
    *m_CreateDate = _T("");
    *m_CreateTime = _T("");
    *m_CreateID = _T("");
    *m_ModifyDate = _T("");
    *m_ModifyTime = _T("");
    *m_ModifyID = _T("");
    m_nFields = 15;
    //}}AFX_FIELD_INIT
    m_nDefaultType = snapshot;
    }void CTestODBCSet::DoFieldExchange(CFieldExchange* pFX)
    {
    //{{AFX_FIELD_MAP(CTestODBCSet)
    pFX->SetFieldType(CFieldExchange::outputColumn);
    RFX_Long(pFX, _T("PartID"), *m_PartID);
    RFX_Text(pFX, _T("PartName"), *m_PartName);
    RFX_Text(pFX, _T("[PartThickness]"), *m_PartThickness);
    RFX_Text(pFX, _T("[PartMaterial]"), *m_PartMaterial);
    RFX_Int(pFX, _T("[PartNum]"), *m_PartNum);
    RFX_Int(pFX, _T("[PartRemain]"), *m_PartRemain);
    RFX_LongBinary(pFX, _T("[PartData]"),* m_PartData);
    RFX_Long(pFX, _T("[BlockID]"), *m_BlockID);
    RFX_Bool(pFX, _T("[Deleted]"), *m_Deleted);
    RFX_Text(pFX, _T("[CreateDate]"), *m_CreateDate);
    RFX_Text(pFX, _T("[CreateTime]"), *m_CreateTime);
    RFX_Text(pFX, _T("[CreateID]"), *m_CreateID);
    RFX_Text(pFX, _T("[ModifyDate]"), *m_ModifyDate);
    RFX_Text(pFX, _T("[ModifyTime]"), *m_ModifyTime);
    RFX_Text(pFX, _T("[ModifyID]"), *m_ModifyID);
    //}}AFX_FIELD_MAP
    }long *m_PartID;
    CString *m_PartName;
    CString *m_PartThickness;
    CString *m_PartMaterial;
    int *m_PartNum;
    int *m_PartRemain;
    CLongBinary *m_PartData;
    long *m_BlockID;
    BOOL *m_Deleted;
    CString *m_CreateDate;
    CString *m_CreateTime;
    CString *m_CreateID;
    CString *m_ModifyDate;
    CString *m_ModifyTime;
    CString *m_ModifyID;
      

  3.   

    以上的2种方法都没有错误使用以下的动态绑定列的方式,就有数据被截断的错误
    pFieldNameList 为变量的链表,在链表中指定变量的类型
    pFieldVariableList 为列名的链表,都是字符串 if(this->m_pFieldNameList != NULL && this->m_pFieldVariableList != NULL)
    {
    pFX->SetFieldType(CFieldExchange::outputColumn);
    CVSListNode *pVarNode  = this->m_pFieldVariableList->GetHead();
    CVSListNode *pNameNode = this->m_pFieldNameList->GetHead(); void *pVarValue;
    CString strNameValue;
    UINT nVarNodeType; for(UINT i=0; i<this->m_nFields; i++)
    {
    pVarValue    = pVarNode->GetNodeData();
    strNameValue.Format("%s",(char *)pNameNode->GetNodeData());
    nVarNodeType = pVarNode->GetNodeType(); switch(nVarNodeType)
    {
    case BIND_SQL_TEXT:
    {
    RFX_Text(pFX, _T(strNameValue), *(CString *)pVarValue);
    break;
    }
    case BIND_SQL_LONG:
    {
    RFX_Long(pFX, _T(strNameValue), *(long *)pVarValue);
    break;
    }
    case BIND_SQL_INT:
    {
    RFX_Int(pFX, _T(strNameValue), *(int *)pVarValue);
    break;
    }
    case BIND_SQL_DOUBLE:
    {
    RFX_Double(pFX, _T(strNameValue), *(double *)pVarValue);
    break;
    }
    case BIND_SQL_FLOAT:
    {
    RFX_Single(pFX, _T(strNameValue), *(float *)pVarValue);
    break;
    }
    case BIND_SQL_DATE:
    {
    RFX_Date(pFX, _T(strNameValue), *(CTime *)pVarValue);
    break;
    }
    case BIND_SQL_BINARY:
    {
    RFX_Binary(pFX, _T(strNameValue), *(CByteArray *)pVarValue);
    break;
    }
    case BIND_SQL_LONGBINARY:
    {
    RFX_LongBinary(pFX, _T(strNameValue), *(CLongBinary *)pVarValue);
    break;
    }
    case BIND_SQL_BYTE:
    {
    RFX_Byte(pFX, _T(strNameValue), *(unsigned char *)pVarValue);
    break;
    }
    case BIND_SQL_BOOL:
    {
    RFX_Bool(pFX, _T(strNameValue), *(int *)pVarValue);
    break;
    }
    default:
    {
    ASSERT(FALSE);
    break;
    }
    }
    pVarNode  = pVarNode->GetNextNode();
    pNameNode = pNameNode->GetNextNode();
    }
    }
      

  4.   

    pVarNode的用法有问题,改为
    case BIND_SQL_TEXT:
    {
    RFX_Text(pFX, _T(strNameValue), *(char *)pVarValue->GetNodeData());
      

  5.   

    用pVarValue->GetNodeData());替代pVarValue,具体的写法要看你的节点数据是怎么保存的
      

  6.   

    pVarValue    = pVarNode->GetNodeData();
    pVarValue是void *类型的
    pVarNode是CVSListNode *类型的其中的数据是void *类型的我把各种与数据库绑定时用到的变量类型都保存在pFieldVariableList 链表中了
    节点的类型就是pVarNode的数据类型
      

  7.   

    数据被截断 指的是数据长度超长 VC里默认是有长度限制的 解决办法如下 在相应字段里处理一下 RFX_Text(pFX, _T("[msgbody]"), m_msgbody, 2400);
      

  8.   

    数据被截断 这个问题我曾经遇到很多次 VC默认似乎是256 很容易超出 你可以以 数据被截断 google一下
    用VC向导静态绑定时VC没有提示 没有报错 不管你数据表字段设成多大
      

  9.   

    CREATE TABLE [dbo].[tbl_PA_Part] (
    [PartID] [int] IDENTITY (1, 1) NOT NULL ,
    [PartName] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,
    [PartThickness] [varchar] (5) COLLATE Chinese_PRC_CI_AS NULL ,
    [PartMaterial] [varchar] (12) COLLATE Chinese_PRC_CI_AS NULL ,
    [PartNum] [smallint] NULL ,
    [PartRemain] [smallint] NULL ,
    [PartData] [varbinary] (1) NULL ,
    [BlockID] [int] NULL ,
    [Deleted] [bit] NULL ,
    [CreateDate] [varchar] (8) COLLATE Chinese_PRC_CI_AS NULL ,
    [CreateTime] [varchar] (8) COLLATE Chinese_PRC_CI_AS NULL ,
    [CreateID] [varchar] (5) COLLATE Chinese_PRC_CI_AS NULL ,
    [ModifyDate] [varchar] (8) COLLATE Chinese_PRC_CI_AS NULL ,
    [ModifyTime] [varchar] (8) COLLATE Chinese_PRC_CI_AS NULL ,
    [ModifyID] [varchar] (5) COLLATE Chinese_PRC_CI_AS NULL 
    ) ON [PRIMARY]
    GO这个是我的表格的SQL脚本,没有哪个数据是超过的啊
      

  10.   

    我还没有进行插入操作呢只是新建了个CRecodeSet的子类然后调用了Open函数就报错了啊
      

  11.   

    再次调试,发现是由于CLongBinary字段的问题,而引起的数据被截断其他的long,int,bool,text都没有问题
    可是RFX_LongBinary没有设置大小的参数啊
      

  12.   

    谁知道SQL中的image字段最大可以放多少字节啊
      

  13.   

    image可变长度二进制数据介于 0 与 231-1 (2,147,483,647) 字节之间
      

  14.   

    谢谢楼上,已经知道了,2GB-------------------------------上次的问题,我把以前使用SQLPUTDATA写到数据库中的数据都删除了,可以执行了但是现在其他的text,long,int,等类型的值可以写入了,而CLongBinary的值却不能写入.而且在MS自己的CRecodeSet的成员函数中出错了void CRecordset::SendLongBinaryData(HSTMT hstmt)
    {
    RETCODE nRetCode;
    void* pv;
    AFX_ODBC_CALL(::SQLParamData(hstmt, &pv));
    if (!Check(nRetCode))
    {
    // cache away error
    CDBException* pException = new CDBException(nRetCode);
    pException->BuildErrorString(m_pDatabase, hstmt); // then cancel Execute operation
    Cancel();
    THROW(pException);
    } while (nRetCode == SQL_NEED_DATA)
    {
    CLongBinary* pLongBinary = (CLongBinary*)pv;
    ASSERT_VALID(pLongBinary); const BYTE* lpData = (const BYTE*)::GlobalLock(pLongBinary->m_hData);
    ASSERT(lpData != NULL); AFX_ODBC_CALL(::SQLPutData(hstmt, (PTR)lpData,
    (SQLLEN)pLongBinary->m_dwDataLength)); ::GlobalUnlock(pLongBinary->m_hData); if (!Check(nRetCode))
    {
    // cache away error
    CDBException* pException = new CDBException(nRetCode);
    pException->BuildErrorString(m_pDatabase, hstmt); // then cancel Execute operation
    Cancel();
    THROW(pException);
    } // Check for another DATA_AT_EXEC
    AFX_ODBC_CALL(::SQLParamData(hstmt, &pv)); 
    ----------------------------------------
    //为什么这里会出错呢?
    //前面nRetCode的值是99,需要数据
    //数据导入后,执行了SQLParamData后nRetCode的值变为了-1
    //报告显示 Error: failure handling long binary value during update.
    ----------------------------------------
    if (!Check(nRetCode))
    {
    TRACE(traceDatabase, 0, _T("Error: failure handling long binary value during update.\n"));
    ThrowDBException(nRetCode, hstmt);
    }
    }
    }
      

  15.   

    image 类型的字段每次必须传入的数据有限制吗?是必须大于32K,还是怎么回事我传了个408个字节的值,他老是报告讲"字符串数据,长度不匹配"
      

  16.   


    //CLongBinary的赋值pType = (LongBinaryType *)pValue;
    pVarValue8->m_hData = ::GlobalAlloc(GMEM_MOVEABLE,pType->nLen);
    pVoid = ::GlobalLock(pVarValue8->m_hData);
    memcpy(pVoid,pType->pData,pType->nLen);
    //::GlobalUnlock(pVarValue8->m_hData);
    pVarValue8->m_dwDataLength = ::GlobalSize(pVarValue8->m_hData);

    this->SetFieldNull(pVarValue8,FALSE);
    this->SetFieldDirty(pVarValue8,TRUE);这里我的CLongBinary的值为"Part is 2 type"在中间没有修改过这个值为什么到了MS的SendLongBinaryData函数中时,就不正确了变成了
    "Part is 2 type铪" 这是MS的语句const BYTE* lpData = (const BYTE*)::GlobalLock(pLongBinary->m_hData);pLongBinary->m_hData的地址与我的CLongBinary->m_hData的地址是一样的有谁知道为什么会出现这个问题啊