随笔 - 30, 文章 - 0, 评论 - 308, 引用 - 11
数据加载中……

运用C#处理lob数据类型 (Oracle)

 

运用C#处理lob数据类型 Oracle

一、           介绍不规则数据类型

随着媒体技术的进步,人们的要求也越来越多,因此现在的数据库中不单单存储简单的数据类型,还可以存储图片、文件、声音等非常庞大的二进制数据,我们把这种不规则数据类型叫做LOBLarge Object)。对于LOB数据即可以存储50K还可以存储50M的二进制数据内容。

Oracle数据库中,大型数据类型有以下几种:

Clob long型相似,clob可以存储单字节型数据

Nclob Nclob存储定宽的多字节国家字符集数据

Blob:可以存储无结构的二进制数据如图片

Bfile Bfile允许对Oracle数据库以外存储的大型二进制文件进行只读形式的访问。和其它三种lob类型数据 不同的是,bfile类型数据存储在一个单独的文件中,该文件不由Oracle来维护。

在这里主要介绍运用C#储存和读取图片(数据库Oracle)。

二、           处理Blob数据项的方式

1.首先介绍数据表结构

表:student

字段名                                       类型                                   说明

STUDENTID                             number                         id关键字段

SNAME                                     varchar2(50)                 姓名

SPHOTO                                    Blob                             图片

定义了序列SEQ_STUDENT_ID

 

2.接着介绍存储Blob数据项方式

注意:Blob数据不能象其它类型数据一样直接插入(INSERT)。插入前必须先插入一个空的Blob对象,BLOB类型的空对象为EMPTY_BLOB(),之后通过SELECT命令查询得到先前插入的记录并锁定,继而将空对象修改为所要插入的Blob对象。

 调用储存过程方式

       http://www.cnblogs.com/surprise/archive/2005/04/19/140461.html

       优点:层次清晰明了,存储速度快

       缺点:运用dbms_lob包用dbms_lob.write()写入只能存储32k以下的图片

 另一种调用储存过程方式

       Oracle中写存储过程如下:

       create or replace procedure update_student_clob (

              id in number,

              file_name in varchar2)

       is

              b_lob  BLOB;

              f_lob   BFILE;

       BEGIN

              --首先把SPHOTO数据插入空值

              Update student set SPHOTO=empty_blob() where STUDENTID=id;

        --通过SELECT命令查询得到先前插入的记录并锁定

        SELECT SPHOTO INTO b_lob from student where STUDENTID=id for update;

        --读取图片文件对象

        f_lob:=bfilename(‘bb_images’, file_name);

              --打开图片文件对象

              dbms_lob.fileopen(f_lob,dbms_lob.file_readonly);

              --图片文件对象写入Blob数据中

              dbms_lob.loadfromfile(b_lob,f_lob,dbms_lob.getlength(f_lob));

              dbms_lob.fileclose(f_lob);

       END;

/

其中:id代表关键字段idfile_name代表文件名 

       bb_images代表目录对象,目录对象创建如下

       create directory bb_images as ‘d:\kk’;

C#中的代码部分与

http://www.cnblogs.com/surprise/archive/2005/04/19/140461.html雷同,在这里就不必多说了

       优点:无论多大的图片都能处理,速度上也非常快

       缺点:只能存储数据库本地的图片

 不用储存过程的方式

       原代码ConsoleApplication2.rar  (推荐,在我们公司项目中就用到了)

优点:解决了所有以上的缺点

缺点:破坏了项目的层次感

 

3.最后介绍读取Blob数据项方式

       原代码WebImage.rar       读取图片的方式比较简单,首先把Blob从数据库中读取出来,接着生成图片格式,最后输出图片就行。

 

以上的方式都是试验成功,如果哪位大虾有更好的方式请随时交流哦

posted on 2005-06-27 15:47 surprise 阅读(6688) 评论(16)  编辑 收藏

评论

#1楼    回复  引用  查看    

如果插入全中文2000到4000个字,就会报错。
2005-06-27 16:07 | 福星人      

#2楼 [楼主]   回复  引用  查看    

什么意思
2005-06-27 16:11 | surprise      

#3楼    回复  引用    

为什么不直接采用ExecuteNonQuery形式?用适配器是不是效率不高?
2005-06-27 17:26 | reokok [未注册用户]

#4楼    回复  引用  查看    

如果blob或clob用来存储文字,如果文字是中文的,字数在2000到4000之间,用c#做插入操作,就会出错,不知道这是不是Oracle的bug还是有什么解决办法.
2005-06-27 19:23 | 福星人      

#5楼 [楼主]   回复  引用  查看    

这确实没试过,我可要试试,试成功了再发上去
2005-06-27 22:02 | surprise      

#6楼 [楼主]   回复  引用  查看    

reokok ,我用过其他方式过但没成功也看了些资料,这方面确实不多,如果你成功了请介绍一下,交流交流
2005-06-27 22:04 | surprise      

#7楼    回复  引用  查看    

我也碰到clob中不能添加2000到4000的中文字,不过java好像是可以的,不知道是不是ADO.NET 的问题。
2005-06-28 08:58 | hawk6224      

#8楼 [楼主]   回复  引用  查看    

有原代码吗,让我看看
2005-06-28 09:24 | surprise      

#9楼    回复  引用  查看    

我看了ConsoleApplication2.rar 的源代码,存储二进制数据采取的一次读入内存的方法,这是很不可取的,如果二进制数据很大,那么一次要划分很多的内存空间。
理想的做法是一次读入一部分数据,写入一部分数据,然后再读取下一部分,写入下一部分,循环至写完全部数据。
在使用ado的时候,对sqlserver和oracle可以使用同样的方法,也不需要存储过程。到了ado.net,需要借助存储过程才能实现,唉,不知道是进步还是退步。
使用ado.net,对sqlserver,ms有示例文章,对oracle没有,看你写了这么多文章,有没有兴趣写一个?
2005-06-28 17:09 | 半梦半醒之间      

#10楼 [楼主]   回复  引用  查看    

我试过用存储过程写过,就是第一个例子上有所改动过,但失败告终老是把后面的内容覆盖掉前面的内容,能不能把Blob数据或二进制分段再用dbms_lob.write()写入这是最好的方式了,我也在研究中
2005-07-01 11:09 | surprise      

#11楼    回复  引用  查看    

我也碰到clob中不能添加2000以上的中文字,有谁解决了?
2005-07-26 15:08 | 吴建明      

#12楼    回复  引用    

原码是什么文件啊,又没个扩展名,用记事本打开全是乱码呢
2005-07-30 12:07 | alan [未注册用户]

#13楼    回复  引用    

create or replace procedure AddBlobPic
(
varID out A_PIC.ID%type,
varPic in A_PIC.Pic%type
)
is

begin

select A_PIC_ID.NEXTVAL into varID from dual;

insert into A_PIC (ID, Pic) values(varID,varPic);

end AddBlobPic;

我写的测试存储过程,直接插入blob(代码中给参数赋值是byte[]),没问题,不过32k的限制还是存在的。
2005-11-30 09:17 | 喝水 [未注册用户]

#14楼    回复  引用    

我试了第三种方法:好象只能存储本地数据库
2005-12-12 10:14 | syf [未注册用户]

#15楼    回复  引用    

不能超过2000个字,你的语句是不是直接sql呢,
我当年用delphi也遇到国,用parameter方式可以解决
不知道现在的ado.net是不是也可以这样解决
2006-03-10 09:47 | howcanido [未注册用户]

#16楼    回复  引用    

chunk`是一次可以读取活写入的大小一般32就够了,但对图就有些不行了。
一般是取得``chunk的大小,然后,用文件流来,用chunk大小来,分几次,干就行了。如果不这样的话,就会有不能转换之类的错误。chunk的设定很影响速度了。
2006-08-31 18:26 | 刚 [未注册用户]

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2005-06-27 16:17 编辑过


相关链接: