CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  数据库

Oracle 和VC++ 高手帮我呀!!小弟先谢谢了!急急急!!!

楼主sxy521(lilic)2004-11-04 10:47:02 在 VC/MFC / 数据库 提问

请教高手,我产生了大量的文本文件(大约都在4k左右)  
  我想将他们存储到Oracle数据库中,是不是应该用BLOB字段,  
  应该怎样存储和读取,我想用VC实现,  
  请问,用ADO可以实现吗?好像还有什么dbms冬冬,  
  具体怎么做??最好,有实例  
  要求:是VC实现!  
  急急急!!!急急急!!!急急急!!!急急急!!!急急急!!! 问题点数:60、回复次数:4Top

1 楼willcheng(寂静之岭)回复于 2004-11-04 11:15:12 得分 0

 
  在pro*c中的处理    
  PRO*C可以用三种方式对LOB字段处理。      
  1、The   DBMS_LOB   package   inside   PL/SQL   blocks.      
  2、OCI   (Oracle   Call   Interface)   function   calls.      
  3、Embedded   SQL   statements.      
  Embedded   SQL   statements.的方式简单而且比较灵活。OTN上提供一个例子:      
  In   this   example   we   will   be   reading   data   from   a   BLOB   with   an   unknown   arbitrary   length   into   a   buffer   and   then   writing   the   data   from   the   buffer   into   an   external   file.      
  Our   buffer   is   small,   so   depending   on   the   size   of   the   BLOB   we   are   reading,   we   may      
  be   able   to   read   the   BLOB   value   into   the   buffer   in   a   single   READ   statement   or   we      
  may   be   required   to   utilize   a   standard   polling   method   instead.      
  First   we   start   off   with   oci.h   and   some   simple   local   variable   declarations      
  example   5.    
  #include   <oci.h>      
  OCIBlobLocator   *blob   ;      
  FILE   *fp   ;      
  unsigned   int   amt,   offset   =   1   ;      
  Now   we   need   a   buffer   to   store   the   BLOB   value   and   then   write   to   the   file   from:      
  #define   MAXBUFLEN   5000      
  unsigned   char   buffer[MAXBUFLEN]   ;      
  EXEC   SQL   VAR   buffer   IS   RAW(MAXBUFLEN)   ;      
  Allocate   the   BLOB   host   variable   and   select   a   BLOB   which   we   will   READ:      
  EXEC   SQL   ALLOCATE   :blob   ;      
  EXEC   SQL   SELECT   a_blob   INTO   :blob   FROM   lob_table   WHERE   ...   ;      
  We   can   then   open   the   external   file   to   which   we   will   write   the   BLOB   value:      
  fp   =   fopen((const   char   *)"image.gif",   (const   char   *)"w")   ;      
  If   the   buffer   can   hold   the   entire   LOB   value   in   a   single   READ   we   need   to   catch   the      
  NOT   FOUND   condition   to   signal   LOB   READ   termination:      
  EXEC   SQL   WHENEVER   NOT   FOUND   GOTO   end_of_lob   ;      
  Now   do   our   first   READ.We   set   the   amount   to   the   maximum   value   of   4   Gigabytes.   It      
  is   larger   than   our   buffer   so   if   the   LOB   doesn't   fit   we   will   READ   using   a   polling      
  mode:      
  amt   =   4294967295   ;      
  EXEC   SQL   LOB   READ   :amt   FROM   :blob   AT   ffset   INTO   :buffer   ;      
  If   we   get   here   then   it   means   that   the   buffer   was   not   large   enough   to   hold   the   entire      
  LOB   value,   so   we   must   write   what   we   have   using   binary   I/O   and   continue   reading:      
  (void)   fwrite((void   *)buffer,   (size_t)MAXBUFLEN,   (size_t)1,   fp)   ;      
  We   use   a   standard   polling   method   to   continue   reading   with   the   LOB   READ   inside      
  of   an   infinite   loop.   We   can   set   up   the   NOT   FOUND   condition   to   terminate   the   loop:      
  EXEC   SQL   WHENEVER   NOT   FOUND   DO   break   ;      
  while   (TRUE)      
  {      
  During   polling,   the   offset   is   not   used   so   we   can   omit   it   in   subsequent   LOB   READs.      
  We   need   the   amount,   however,   because   it   will   tell   us   how   much   was   READ   in   the      
  last   READ   invocation      
  EXEC   SQL   LOB   READ   :amt   FROM   :blob   INTO   :buffer   ;      
  (void)   fwrite((void   *)buffer,   (size_t)MAXBUFLEN,   (size_t)1,   fp)   ;      
  }      
  Here,   we   have   reached   the   end   of   the   LOB   value.   The   amount   holds   the   amount   of      
  the   last   piece   that   was   READ.   During   polling,   the   amount   for   each   interim   piece      
  was   set   to   MAXBUFLEN,   or   the   maximum   size   of   our   buffer:      
  end_of_lob:      
  (void)   fwrite((void   *)buffer,   (size_t)amt,   (size_t)1,   fp)Top

2 楼TrueIAm(阿 成)回复于 2004-11-04 13:52:46 得分 0

willcheng(寂静之岭),讲得好.........Top

3 楼tabby(-_-b .. 内存泄漏)回复于 2004-11-04 14:02:41 得分 60

使用ADO实现BLOB数据的存取   --   ADO开发实践之二  
   
  一、前言  
  在上一篇文章《ADO第一次亲密接触》中我们详细介绍了ADO基本的操作方法,在实际的开发过程中我们常常需要存储较大的二进制数据对象,比如:图像、音频文件、或其它二进制数据,这些数据我们称之为二进制大对象BLOB(Binary   Large   Object),其存取的方式与普通数据有所区别。本文将介绍利用ADO在数据库中存取BLOB数据的具体实现过程,并给出实现图像存取显示的完整示例工程。  
   
  二、前期准备  
  首先我们建立一张名为userinfo的表,包含三个字段:id,username,old,photo,其中photo是一个可以存储二进制数据的字段。  
  2.1   在SQL   SERVER中我们可以在Query   Analyzer中直接输入如下语句创建:  
   
  CREATE   TABLE   [dbo].[userphoto]   (  
    [id]   [int]   IDENTITY   (1,   1)   NOT   NULL   ,  
    [username]   [varchar]   (50)   NULL   ,  
    [old]   [int]   NULL   ,  
    [photo]   [image]   NULL    
  )   ON   [PRIMARY]   TEXTIMAGE_ON   [PRIMARY]  
  其中photo我们定义为image类型的字段。  
   
  2.2   在ACCESS中创建的方法如下:  
  建立一张新表包括id,username,old,photo四个字段,然后打开表,选视图菜单中设计视图,将id设置为自动编号的递增长整型,username为文本,old为数字,photo为OLE对象。  
  在我们的示例工程中已经包含了一个建立好的ACCESS2000的库,你可以直接拿来使用。  
   
  三、具体步骤  
  3.1   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();                                                                                             ///保存我们的数据到库中  
  至此我们的数据已经成功地保存到了数据库中,接下来我们所要做的工作便是将该数据提取出来,让我们继续吧!  
   
  3.2   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);  
        }  
  }  
  以上我们成功实现了BLOB数据在数据库中的存取,为了让大家有现成的例子可以参考,本文提供了示例工程,在示例工程中我们在数据库中保存图像数据,并可以对这些图像进行浏览、修改,该例子还涉及到如何用char   *指向的BMP文件数据创建BITMAP对象然后显示出来。Top

4 楼sxy521(lilic)回复于 2004-11-04 20:59:38 得分 0

create   table   testlob(  
          id             number,  
          lob1         clob  
  );  
   
  insert   into   testlob   (id,lob1)   values(1,'abc');  
   
  create   or   replace   procedure   sp_testlob_1  
  is  
          bfTestFile     BFILE;  
  lobReturn     CLOB;  
  begin  
      select   lob1   into   lobreturn   from   testlob   where   id=1   for   update;  
      bfTestFile   :=   BFILENAME('DIR_LOB_1','lob.txt');  
      dbms_lob.fileopen(bftestfile,dbms_lob.file_readonly);  
      dbms_lob.loadfromfile(lobreturn,bftestfile,dbms_lob.getlength(bftestfile));  
      commit;  
      dbms_lob.fileclose(bftestfile);      
  end   sp_testlob_1;  
   
  其中lob.txt为纯文本文件  
   
  请问::::  
  bfTestFile   :=   BFILENAME('DIR_LOB_1','lob.txt');  
  中的'DIR_LOB_1',是不是文件路径呀??  
  bfTestFile   :=   BFILENAME('C:\\','lob.txt');  
  我这样怎么不可以呀??  
  大虾救我呀  
  Top

相关问题

  • 有分加。急!急!急!(VC++)
  • 急,急!ORACLE罢工!
  • 【急急急急急急问】Oracle 9i怎么备份?????
  • 【急急急急急急问】Oracle 9i怎么备份?????
  • 【急急急急急急问】Oracle 9i怎么备份?????
  • VC连接出错,急!急!急!急!
  • JDBC访问Oracle数据库,出现异常!!!!急急急急急急急
  • 急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急急
  • 怎么在vc的工程里去掉一个文件。?急急急急急急急急急急
  • 高分!!如何用vc在新窗口中弹出网页,急急急急急急急急急急急急急急!!!

关键词

  • 数据
  • 字段
  • 函数
  • 二进制
  • dbms
  • 指针
  • 原型
  • lob
  • bftestfile
  • blob

得分解答快速导航

  • 帖主:sxy521
  • tabby

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo