《PB大文本对象处理》由会员分享,可在线阅读,更多相关《PB大文本对象处理(4页珍藏版)》请在金锄头文库上搜索。
1、PB-大文本(Blob)对象处理*Blob类型的数据用来保存象大文本和图象之类的数据,这种数据长度很大、几乎没有限制。而在PB中,没有长度限制的对象仅此一种类型,所以它有特殊的处理方法。Blob类型的数据没有边界限制,可以保存一些普通类型的字段不能保存的信息。以下情况下考虑使用Blob类型的字段:a)要保存OLE对象(如图形、声音等)时;b)将大型的二进制对象存入数据库中时:c)当文本对象过大,以至于一般的字符串函数无法对其操作时;d)数据库中有PB不能支持的数据类型时。普通类型的字段使用数据窗口,通过调用函数Update和Commit事务管理语句就可以保存数据了。但Blod类型的数据非常庞大
2、,所以这种类型字段的更新不能像普通的字段,只能用其特有的语句进行更新。Updateblob的语法格式如下:Updateblob 表名 set Blob类型字段名 = :Blob类型变量 where 子句;上面的语法和Update语法类似,除了使用关键字Updateblob外,其他和Update语法都相同。普通类型的字段显示是通过数据窗口,调用Retrieve即可。但是,由于Blob类型的数据非常庞大,客户端的主缓存区开辟多么大的空间都不合适。PowerBuilder的解决方法是,不允许在数据窗口中放置Blob类型的字段,而是提供专用的提取Blob类型数据的语句。该语句语法如下:Selectbl
3、ob Blob类型的列名 into :Blob类型变量 from 表名 where 子句;上面的语法同Select语句类似,只是使用了关键字Selectblob。另外,Selectblob和Updateblob中的where子句都必须只能返回一行数据,也就是说,一次只能处理一个Blob类型的数据。关于Blob类型的处理只能通过上面的两个语句来进行。不像普通类型的字段那样数据的更新可以通过Insert语句实现。所以,在使用Updateblob语句之前,符合where子句条件的数据已经存在了,并且只存在一条数据。因此,如果想把大文本或者图像等Blob类型的数据写入数据库,必须首先插入这条记录的其他
4、部分,然后再通过修改记录的方式将Blob类型数据写入。*因为大文本对象特别庞大,当使用Updateblob时应该将事务对象的Autocommit设置为True,这很容易理解。因为这么庞大的数据量要求一次提交,显然多大的缓冲内存都不合适,只能让事务对象在合适的时候自动提交了。*DBMS中的数据类型可以在PowerScript中与Blob数据类型相对应,如在Oracle对应为longraw,raw。在MS SQL Server中对应为image,text。在DB2/2中对应为N/A。*实例假设在一个应用系统中,进行合同管理时要保存合同的原样,以便以后的责任审查。用图像扫描设备将合同扫描成图形文件,
5、以图像方式保存到数据库中,这就涉及了Blob类型的处理该软件实现时,最重要的首先是图像的保存,然后是图像的显示问题。假设在窗口w_contract上左边是dw_1,在dw_1上显示合同中的相关数据,用户选择不同的数据行时,对应的合同文本显示在picture控件p_1上;用户点击“录入合同文本”按钮时打开w_htwb_input窗口选择合同文本对应的图形文件名称,返回后根据该文件大小进行相关处理,并保存到数据库中。数据窗口dw_1从contract数据表中提取数据,该数据窗口中不包括Blob类型的字段htwb,其主键为合同编号(htbh)。当数据窗口的行焦点改变时读取该行中的合同文本,并显示在p
6、icture控件p_1上。在数据窗口的rowfocuschanged事件中编写脚本如下:blob lbb_pic /用来保存图片string ls_htbh /用来保存合同编号if currentrow 0 thenselectblob htwb into :lbb_pic from contract where htbh = :ls_htbh;/读取图象if len(lbb_pic) 0 thenp_1.setpicture(lbb_pic)elsebeep(2)messagebox(提示,ls_htbh + 号合同没有录入合同文本!,information!)end ifenf ifset
7、pointer(arrow!)在“录入合同文本”按钮的clicked事件中编写脚本,弹出另外一个response类型的窗口w_htwb_input,让用户在该窗口中选择要录入的合同文本的图形文件,返回后读取该文件并保存到数据库中。因为fileread函数一次读取的文件不能大于32KB,如果大于32KB就只能以32KB为单位分多次读取。脚本如下:string ls_pic,ls_htbhinteger li_i,li_fileptr,li_loopslong ll_filelen,ll_bytes_read,ll_new_posblob lbb_read,lbb_totalif dw_1.mod
8、ifiedcount() 0 then /确保其他数据已经提交beep(2)messagebox(提示,请先保存再录入合同文本!,information!)returnelse /如果没有修改过,则判断是否有合同号(如果没有合同号则肯定不能提交)ls_htbh = trim(dw_1.getitemstring(dw_1.getrow(),htbh)if len(ls_htbh) = 0 thenbeep(2)messagebox(提示,必须首先录入合同好,才能录入合同文本!,stopsign!)returnend ifend ifopen(w_htbh_input) /打开合同文本录入窗口l
9、s_pic = message.stringparmsetpointer(hourglass!)ll_filelen = filelength(ls_pic) /获取文件的长度li_fileptr = fileopen(ls_pic,streammode!,read!,lockread!)if li_fileptr -1 thenbeep(2)messagebox(错误,图形文件打开错误!,information!)returnend ifif_filelen 32766 thenli_loops = (li_filelen - 1)/32766 + 1elseli_loops = 1end
10、iffor li_i = 1 to li_loopsll_bytes_read = fileread(li_fileptr,lbb_read)lbb_total = lbb_total + lbb_readll_new_pos = ll_new_pos + ll_bytes_readfileseek(li_fileptr,ll_new_pos,frombeginning!)nextfileclose(li_fileptr)setpicture(p_1,lbb_total)sqlca.autocommit = trueupdateblob contract set htwb = :lbb_total where htbh = :htbh_str;sqlca.autocommit = falseif sqlca.sqlcode = -1 thenmessagebox(失败,sqlca.sqlerrtext)elseif sqlca.sqlcode = 100 thenmessagebox(失败,ls_htbh + 号合同没有找到!,information!)end if在窗口w_htwb_input窗口中,提供让用户选择文件名称的功能。这部分的脚本比较简单并且也和Blob的处理关系不大,不再赘述。