利用oracle数据库的blob字段保存各种文件的方法

时间:2022-07-22 07:33:00

利用oracle数据库的blob字段保存各种文件的方法

摘要:在日常工作中,许多单位或企业都累积了大量的文件。如何保存和组织这些文件,如何高效地查阅和使用它们,则成了一个普遍存在的问题。为解决这一问题,用powerbuilder作为开发工具编写了一个小软件,通过运行特殊的SQL语句,将各种文件保存于oracle的二进制大字段中,并可以随时查看和下载文件。

关键词:文件;二进制大字段;SQL语句;powerbuilder

中图分类号:TP311文献标识码:A文章编号:1009-3044(2012)22-5271-04

Using Binary Large Field to Save all Documents Method

LU Xiao-li

(Guangxi Nanning City State Taxation Bureau , Nanning 530022, China)

Abstract: In their daily work, many units or enterprises have accumulated a lot of documents.How to store and organize these documents, how to effectively access and use them, then became a widespread problem.In order to solve this problem, using PowerBuilder as a designer tool to write a small software, by running a special SQL statements, the files are stored in the Oracle binary large field, and can be readily viewed and downloaded .

Key words: documents; binary large field; SQL statement; powerbuilder

在日常工作中,各单位或企业都累积了大量的文件,如WORD文档,EXCEL文档、多媒体文档、图片等。如何保存和组织这些文件,如何高效地查阅和使用它们,则成了一个普遍存在的问题。

例如:该如何分门别类地保存和组织大量文件?该如何保证每台客户端中看到的都是最新修改过的文件?

笔者在本单位的软件开发中就遇到类似问题。作者所要求开发的一个软件,要求每台客户端都能通过该软件,及时上传和浏览打印各种最新的文档。

为解决这个问题,通过查阅大量资料后,笔者决定用oracle数据库的blog字段,来解决文件的保存和查询问题。并且用power builder作为程序开发工具,开发出一个小软件。该软件可以上传各种文档、图像、二进制文件、多媒体文件等到oracle数据库中,并可以随时查看和下载。

1原理及技巧

随着计算机技术的不断发展和普及,数据库,尤其是关系型数据库,在日常工作和生活中也得到了普遍应用。

关系型数据库中,一般常用的字段有字符型、数值型、日期型、逻辑型等类型。但还有一种特殊的字段,是以二进制形式存放数据的,长度是0~2GB字节,这就是二进制大字段。如oralce、mysql、access中的blog字段。由于数据是以最基本的二进制保存,不论其原来的数据是简单的类型还是复杂的类型,数据库都只当其是一连串的二进制数据,因此,就解决了各种文档、图像、多媒体等各种文件的存储问题。

在powerbuilder中,主要是利用blog变量和fileread语句或filewrited语句来从文件中读取数据或写数据,再用到两条特殊的SQL命令——UPDATEBLOB和SELECTBLOB,来跟数据库进行交互。具体见图1。

图1过程图

一个table中,blog字段不能单独存在,至少要有一个常规字段,用来标识一条记录。

由于blog字段比较特殊,对其进行操作的sql语句也比较特别。

添加数据时,要先insert一个空的blog字段,再用updateblob语句将二进制数据添加进去。

导出数据时,用selectblob语句查询导出。

例如:

insert into test_photo (id,photo) values(‘01’,empty_blob())

updateblob test_photo set photo=:b1 where id=’01’( b1是pb中blog类型的变量)

selectblob photo into :b1 from test_photo where id=’01’( b1是pb中blog类型的变量)用其他的软件开发工具也是类似。

2程序结果

该小程序运行后出现如图2的界面,程序的代码附在文后。

图2运行结果图

窗口的左半部是pb的ole控件,点击后可以直接打开word文档或excel文档。对于其他类型的文件,还不支持直接打开,可下载后在操作系统中打开或运行。

主要程序代码:(代码都已测试通过)

上传按扭的代码

blob m_b1 ,m_b2

blob tot_b

string s1 ,s2,s3,file1, m_filename , m_hz

long n1,jj ,li_fnum ,li_bytes , ii,ll,loops ,nbr,m_count

ll=getfileopenname(’选择文件’,path1,file1,’’,’file(*.*),*.*’,’c:\’ )

if ll<>1 then

messagebox(’’,’没选中文件’)

return

end if

st_1.text=file1

m_filename=st_1.text

m_hz=right(file1,3)

setnull(tot_b)

setnull(m_b1)

m_count=0

select count(*) into :m_count from test_photo where id=:file1 ; //查看数据库中是否有同名文件

if m_count>1 then

messagebox(’’,’已有同名文件!’)

return

end if

li_bytes=filelength(path1)

li_fnum = fileopen(path1, streammode!)

if li_fnum>0 then

if li_bytes > 32765 then//一次只能读32765字节,要先判断读几次

if mod(li_bytes, 32765) = 0 then

loops = li_bytes/32765

else

loops = (li_bytes/32765) + 1

end if

else

loops = 1

end if

for ii = 1 to loops

jj = fileread(li_fnum, m_b1) //将文件分次读入bolb变量

tot_b=tot_b + m_b1//若大于32765字节,将bolb变量内容加起来

next

m_b2=blobmid(tot_b,1,li_bytes)

insert into test_photo (id,photo,hz) values(:m_filename,empty_blob(),:m_hz) ;//增加记录

updateblob test_photo set photo=:tot_b where id=:m_filename ; //上传bolb变量的内容

if sqlca.sqldbcode = 0 then

commit ;

messagebox("","保存成功!")

else

messagebox("sql error", sqlca.sqlerrtext)

end if

else

messagebox(’’,’无法打开文件!’)

end if

fileclose(li_fnum)

dw_1.retrieve()

下载按扭的代码

long ii,jj ,li_FileNum ,li_bytes ,loops,m_row

integer rtn

string m_id,m_hz,m_ml,s2,m_file

blob b1 ,tob_b

setnull(b1)

m_row=dw_1.getrow()

if m_row>0 then

st_1.text=dw_1.object.id[m_row]

m_ml=trim(sle_1.text)

m_id=trim(st_1.text)

m_hz=right(m_id,3)

m_file=m_ml+"/"+m_id

if DirectoryExists(m_ml)=false then

messagebox(’’,’指定下载目录不存在!’)

return

end if

messagebox(’’,’开始下载!’)

selectblob photo into :b1 from test_photo where id=:m_id;

//messagebox(’sqlca.SQLCode’,sqlca.SQLCode )

if not isnull(b1) then

li_FileNum = FileOpen(m_file , StreamMode!, Write!, Shared!, replace!)

li_bytes=len(b1)

//messagebox(’’,string(li_bytes))

jj= FileWriteex(li_FileNum, b1)

fileclose(li_FileNum)

messagebox(’’,’文件’+m_file+’下载完毕!’)

else

messagebox(’’,’无文件内容!’)

end if

end if

打开按扭的代码(先下载,再打开)

long ii,jj ,li_filenum ,li_bytes ,loops,m_row

integer rtn

string m_id,m_hz,m_ml,s2,m_file

blob b1 ,tob_b

setnull(b1)

m_row=dw_1.getrow()

if m_row>0 then

st_1.text=dw_1.object.id[m_row]

m_ml=trim(sle_1.text) //取出默认下载路径

m_id=trim(st_1.text)

m_hz=right(m_id,3)

m_file=m_ml+"/aaaa."+m_hz

choose case upper(m_hz) //根据不同类型使用不同语句打开

case ’doc’

ole_1.insertclass(’word.document’)

case ’xls’

ole_1.insertclass(’excel.sheet’)

case else

messagebox(’抱歉’,’本程序只能自动打开doc文件或xls文件,其他类型文件请下载后再在程序外打开。’)

return

end choose

selectblob photo into :b1 from test_photo where id=:m_id; //导出bolb字段内容

if not isnull(b1) then

li_filenum = fileopen(m_file , streammode!, write!, shared!, replace!)

li_bytes=len(b1)

jj= filewriteex(li_filenum, b1) //将bolb变量内容写成文件

// filewriteex命令可以写入大于32765字节的文件

fileclose(li_filenum)

ole_1.insertfile(m_ml + m_id) //利用ole打开文档

ole_1.doverb(7)

filedelete(m_file)

else

messagebox(’’,’无文件内容!’)

end if

end if

3结束语

该方法有四大优点:

1)更新及时。若采取文件拷贝的方式,则不一定保证自己手上的文档内容是最新的版本。而采用在程序中下载或打开的方法,则可以保证看到的是最新更新的文件;

2)保密性强。在服务器端,文件是以二进制的形式存储在数据库里,比起用文件形式的存放,保密性当然提高了很多;在客户端,则可以在程序中设置权限,决定哪些文件给哪些人看,保密性也同样增强了;

3)易分类保存和查询。可以设置一些辅助字段,如文件类型、文件名、上传人、上传时间、说明及备注等,便于查询和分类统计;

4)易于备份。Blog字段可以跟oracle普通的字段一起,通过exp命令导出,形成dmp文件进行备份;

该软件的不足之处是Client/Server类型的程序,每台客户端都要安装软件。

参考文献:

[1]丁钺,廖小平.powerbuilder7.0,高级开发指南[M].北京:人民邮电出版社,2000.

[2]互联网在PowerBuilder中操作BLOB数据的技巧-PB编程技巧-华软源码[EB/OL]. .

上一篇:持久保护与融合创新 下一篇:光明草最后的预言