我想用ado的记录集的open方法打开带有blob类型的表(oracle9i数据库),但是跟踪函 
数发现不能成功打开。用oracle的worksheet用sql语言查询也不能打开,但是这是因为 
worksheet无法显示blob类型,所以可以理解。 
但是ado功能这么强大,为什么也打不开呢,太郁闷了,不可能ado就不能往oracle里面 
插入二进制文件吧,简直是玩笑,不知道各位大侠能否指点小弟一下,感激! sql.Format("select * from docman_dba.Doc_R  where DocId=%d",*dID); 
Doc_R 这个表包含文档id和一个附件(docattach),附件类型是blob类型的。 
真是郁闷,就是死活不能成功返回。

解决方案 »

  1.   

    首先ado可以打开blob类型的字段
    请把你的open语句贴出来看看
      

  2.   

    ADO可以用来操作blob类型的数据的,楼主可以好好看看这篇文章
    http://www.vckbase.com/document/viewdoc.asp?id=252这个是oracle中存图片的代码
    VARIANT   varBLOB;
    SAFEARRAY  *psa;
    SAFEARRAYBOUND rgsabound[1];if(pBuf)
    {    
         rgsabound[0].lLbound = 0;
         rgsabound[0].cElements = p_nLen;
         psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
    for (long i = 0; i < (long)p_nLen; i++)
          SafeArrayPutElement (psa, &i, pBuf++);
    varBLOB.vt = VT_ARRAY | VT_UI1;
    varBLOB.parray = psa;
    m_pImageRecordset->GetFields()->GetItem("pic")->AppendChunk(varBLOB);
    }
       m_pImageRecordset->Update();
      

  3.   

    open语句如下:
    try
    {
    m_pRecordSet->Close();
    m_pRecordSet->Open((_bstr_t)sql.AllocSysString(),
    _variant_t((IDispatch *)m_pConnection,true),
    adOpenDynamic,adLockPessimistic,adCmdText);
    m_pRecordSet->Fields->GetItem("DocTest")->AppendChunk(varChunk);
    }
    其中sql语句为sql.Format("select * from DOCMAN_DBA.DOC_R where docid=%d",*dID);
    一些测验结果:一、access数据库的blob类型打开均无问题,oracle不行。
    二、我如果在sql语句中不选择打开blob类型,则没有问题。open语句能够通过。
    三、我另外建了long raw类型的列,此列的open方法也能通过。
    我实在不相信oracle数据库会比其他数据库差。我用google搜了很多文章,象三楼提供的网页我也看了,但是是对access的。也有些文章提出要用oo4o的方法连接oracle,说ado不能打开blob类型,难道是真的?
      

  4.   

    我用VC操作过MYsql的BLOB类型,用的是mysql的CAPI,一切正确.建立你也使用oracle的CAPI,还有一点,我发现mysql的blob类型与access的ole类型在存储二进制时,如一张图片,格式不一样,不能互相用,不知oracle如何?
      

  5.   

    程序如下:
    BOOL CCoracleDlg::CreateDoc(DWORD diID, CFile & f, DWORD *dID)
    {
    //////////////外部变量////////////////////////////////////////////// CString m_strDocName="三等功";
    DWORD   dwUserID=11111;
    CString strDate="21-12月-2003";
    DWORD   m_strShareLevel=0;
    CString m_strDocCode="2004三等功";
    CString m_strDocAbstract="一部一局二组组长局内共享文档";
    CString m_strDocKey="三等功人员";
    int     nNumber=2;
    CString strAttributeNameArray[2]={"名称","日期"};
    CString strAttributeValueArray[2]={"三等功","21-12月-2003"};

    /////////////////////////////////////////////////////////////////////
    CString sql;

    CCoracleApp* p=(CCoracleApp *)AfxGetApp();//////////////开始将该文档插入主表////////////////////////////////////////////////////////////////////////// sql.Format("insert into docman_dba.DocMain values(docman_dba.DocMain_seq.nextval,%d,%d,%d,'%s',sysdate,'%s','%s','%s',0,'%s')",diID,m_strShareLevel,dwUserID,strDate,m_strDocCode,m_strDocAbstract,m_strDocKey,m_strDocName);
    ///////////////事务开始//////////////////////////////////////////
    p->cOracleInterface.m_pConnection->BeginTrans();
    try
    {
    if(!(p->cOracleInterface.ExecuteSQL(sql))) return NULL;
    sql.Format("select docman_dba.DocMain_seq.currval from dual");
    if(!(p->cOracleInterface.GetSequenceCurrval(sql,dID))) return NULL;

    ////////////////////写文档定制属性///////////////////////////////////////////////////////////////////////
    DWORD docproid;
    for(int i=0;i<nNumber;i++)
    {
    sql.Format("select DocProId from docman_dba.Doc_ProDic where DocProName='%s'",strAttributeNameArray[i]);
    if(!(p->cOracleInterface.GetSequenceCurrval(sql,&docproid))) return NULL;
    sql.Format("insert into docman_dba.Doc_Pro values(%d,%d,'%s')",*dID,docproid,strAttributeValueArray[i]);
    if(!(p->cOracleInterface.ExecuteSQL(sql))) return NULL;

    }
    ///////////////写入附件////////////////////////////////////////////////////////
    sql.Format("insert into docman_dba.Doc_R (DOCID ) values(%d )",*dID);
    if(!(p->cOracleInterface.ExecuteSQL(sql))) return NULL;

    sql.Format("select docid,docattach from DOCMAN_DBA.DOC_R where docid=%d",*dID);

    if(!(p->cOracleInterface.WriteDocAttach(sql,f))) return NULL;
    p->cOracleInterface.m_pConnection->CommitTrans();
    }
    catch(_com_error e)
    {
    p->cOracleInterface.m_pConnection->RollbackTrans();
    return NULL;
    } f.Close();
    return 1;
    }WriteDocAttach写文档附件(blob类型插入):
    BOOL COracleInterface::WriteDocAttach(CString sql,CFile & f)
    {
    int  ChunkSize=1024;
    char buffer[1025];
    VARIANT varChunk;
    SAFEARRAY *psa;
    SAFEARRAYBOUND rgsabound[1];
    int uIsRead=0;

    while(1)
    {
    uIsRead=f.Read(buffer,ChunkSize);
    if(uIsRead==0) break;
    rgsabound[0].cElements=uIsRead;
    rgsabound[0].lLbound=0;
    psa=SafeArrayCreate(VT_UI1,1,rgsabound);
    for(long index=0;index<uIsRead;index++)
    {
    if(FAILED(SafeArrayPutElement(psa,&index,&buffer[index])))
    return 0;
    }
    varChunk.vt=VT_ARRAY|VT_UI1;
    varChunk.parray=psa;
    try
    {
    m_pRecordSet->Close();

    m_pRecordSet->CursorType = adOpenKeyset;
    m_pRecordSet->LockType = adLockOptimistic; m_pRecordSet->Open((_bstr_t)sql.AllocSysString(),
    _variant_t((IDispatch *)m_pConnection,true),
    adOpenDynamic,adLockPessimistic,adCmdUnknown);

    m_pRecordSet->Fields->GetItem("DocAttach")->AppendChunk(varChunk);
    }
    catch(_com_error e)
    {
    return NULL;
    }
    ::VariantClear(&varChunk);
    ::SafeArrayDestroyData(psa);
    if(uIsRead<ChunkSize)
    break;
    }
    m_pRecordSet->Update();
    f.Close();

    return 1;
    }
    程序在m_pRecordSet->Open............就是不能成功返回.CAPI确实能够做这些东西吗?它与数据库是怎么打交道的.
      

  6.   

    C API 是指 MYSQL 提供的C 接口库 当然什么都可以做
      

  7.   

    ado是无法打开oracle的blob的(最新的情况不知道),因为ado的oracle驱动不支持操作oracle的blob字段,你可以考虑一下用long raw来代替,或者用ado.net/jdbc/oo4o/oci等库来操作oracle
      

  8.   

    OLEDB行吗?我是用vc来开发的。这个开发环境是不能变的了
      

  9.   

    oledb和ado底层用的驱动是一样的,所以也不可以,这个问题当时我们折腾了好久。
    ado.net/jdbc/oo4o/oci
    都可以在vc7下面用啊!