我现在在做毕业设计,有个难题困扰着我,在Edit框中所画的图形,如何添加到数据库中,我的数据库是用MS-SQL建立的,基于ADO技术,如何实现啊,
表中有2个字段,一个是图形数据,类型为2进制,另外一个是图形ID号,类型为整型
此工程是基于Dialog建立的,有一个Edit框,一个实现画图按钮,一个用于保存的按钮

解决方案 »

  1.   

    char *pBuf = m_pBMPBuffer;
    VARIANT varBLOB;
    SAFEARRAY *psa;
        SAFEARRAYBOUND rgsabound[1];
    m_pRecordset->AddNew();
    m_pRecordset->PutCollect("username",_variant_t(m_UserName));
    m_pRecordset->PutCollect("old",atol(m_Old));
    if(pBuf)
    {    
    rgsabound[0].lLbound = 0;
    rgsabound[0].cElements = m_nFileLen;
    psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
    for (long i = 0; i < (long)m_nFileLen; i++)
    SafeArrayPutElement (psa, &i, pBuf++);
    varBLOB.vt = VT_ARRAY | VT_UI1;
    varBLOB.parray = psa;
    m_pRecordset->GetFields()->GetItem("photo")->AppendChunk(varBLOB);
    }
      

  2.   

    http://www.vckbase.com/document/viewdoc.asp?id=252
      

  3.   

    BLOB数据的保存
    BLOB类型的数据无法用普通的方式进行存储,我们需要使用AppendChunk函数,AppendChunk包含在Field对象中,原型如下:
    HRESULT AppendChunk (const _variant_t & Data );
    从函数原型中可以看到关键的问题是我们需把二进制数据赋值给VARIANT类型的变量,下面我们给出具体的代码并作简单的分析:
     
    ///假设m_pBMPBuffer指针指向一块长度为m_nFileLen的二进制数据,并且已经成功打开了记录集对象m_pRecordset///char *pBuf = m_pBMPBuffer;       //注意他是字节型的
    VARIANT varBLOB;
    SAFEARRAY *psa;
    SAFEARRAYBOUND rgsabound[1];             //绑定m_pRecordset->AddNew();                                              ///添加新记录
    m_pRecordset->PutCollect("username",_variant_t("小李"));             ///为新记录填充username字段
    m_pRecordset->PutCollect("old",_variant_t((long)28);                 ///填充old字段
    if(pBuf)
    {    
       rgsabound[0].lLbound = 0;
       rgsabound[0].cElements = m_nFileLen;
       psa = SafeArrayCreate(VT_UI1, 1, rgsabound);                      ///创建SAFEARRAY对象
       for (long i = 0; i < (long)m_nFileLen; i++)
          SafeArrayPutElement (psa, &i, pBuf++);                         ///将pBuf指向的二进制数据保存到SAFEARRAY对象psa中
       varBLOB.vt = VT_ARRAY | VT_UI1;                                   ///将varBLOB的类型设置为BYTE类型的数组
       varBLOB.parray = psa;                                             ///为varBLOB变量赋值
       m_pRecordset->GetFields()->GetItem("photo")->AppendChunk(varBLOB);///加入BLOB类型的数据

    m_pRecordset->Update();                                              ///保存我们的数据到库中
    至此我们的数据已经成功地保存到了数据库中,接下来我们所要做的工作便是将该数据提取出来 BLOB数据的读取
    对应于保存数据时我们所使用的AppendChunk函数,读取数据应该使用GetChunk函数,GetChunk的原型如下:
    _variant_t GetChunk (long Length );
    给出数据的长度后GetChunk将返回包含数据的VARIANT类型变量,然后我们可以利用SafeArrayAccessData函数得到VARIANT变量中指向数据的char *类型的指针,以方便我们的处理,具体代码如下:long lDataSize = m_pRecordset->GetFields()->GetItem("photo")->ActualSize;///得到数据的长度
    if(lDataSize > 0)
    {
       _variant_t varBLOB;
       varBLOB = m_pRecordset->GetFields()->GetItem("photo")->GetChunk(lDataSize);
       if(varBLOB.vt == (VT_ARRAY | VT_UI1))                                 ///判断数据类型是否正确
       {
            char *pBuf = NULL;
            SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);              ///得到指向数据的指针
            /*****在这里我们可以对pBuf中的数据进行处理*****/
            SafeArrayUnaccessData (varBLOB.parray);
       }
    }
      

  4.   

    建议使用ADO2.5的Stream对象。它用起来比较方便。下面给出一段代码供参考。
    要求其字段类型为image。CoInitialize(NULL);
    try
    {
             _RecordsetPtr pRs;
    pRs.CreateInstance(__uuidof(Recordset));
    _StreamPtr pStm;
    pStm.CreateInstance(__uuidof(Stream));
    //
    CString cnString=_T("Provider=sqloledb;Data Source=zy;"
    "Initial Catalog=chm;User Id=chm;Password=chm;");
    //
    CString tablename=_T("table1");
    pRs->Open(_variant_t(tablename),
    _variant_t(cnString),
    adOpenDynamic,adLockOptimistic,adCmdTable);
    //
    pRs->MoveFirst();
    _variant_t varOptional(DISP_E_PARAMNOTFOUND,VT_ERROR); 

    pStm->Open(varOptional,adModeUnknown,adOpenStreamUnspecified,_T(""),_T(""));
    pStm->Type=adTypeBinary;
    //
             adOpenStreamUnspecified,NULL,NULL);
    pStm->LoadFromFile(_bstr_t("F:\\example.bmp"));//也可以是视频文件 pRs->Fields->GetItem(long(0))->Value=pStm->Read(adReadAll);
    pRs->Update(); pStm->Close();
    pRs->Close();
    }
    catch(_com_error& e)
    {
    CString s=_T("数据库操作错误!\n");
    s=s+(char*)e.Description();
    MessageBox(s,_T("错误"),MB_OKCANCEL|MB_ICONERROR);
    }
    //
    CoUninitialize();