起因:
水晶报表需要显示从数据库中获取的图片,可是数据库表中只存储一个图片文件路径,并没有保存为BLOB字段,而水晶报表却不能根据文件路径显示该图片。
解决思路:报表查询时将链接转为BLOB字段存储,或者将所有链接转化为BLOB字段存储到表中。
最终还是没有如愿L,虽然语法基本上来自网上,不过还是了解了一下UTL_FILE和DBMS_LOB包的使用方法。
修正一个错误,尽管BLOB字段不能转化回图片文件,但是BLOB字段本身保存的图片信息还是正确的,因此水晶报表还是能够正常显示BLOB图片的,:)
[@more@]1.创建目录和BLOB表
CREATE DIRECTORY PIC AS 'D:PIC'; CREATE TABLE TEST ( Name varchar2(20), Content BLOB ); |
2.下面有几张picture,分别用来测试使用
-
Plan.bmp 148k
-
red.bmp 1.2k
-
other.jpg 17K
3.把图片写入大字段中,并检查写入情况,一切正常
declare a_blob BLOB; a_bfile BFILE := BFILENAME('PIC','red.bmp'); begin insert into test values ('red.bmp',empty_blob()) returning content into a_blob; dbms_lob.fileopen(a_bfile); dbms_lob.loadfromfile(a_blob, a_bfile, dbms_lob.getlength(a_bfile)); dbms_lob.fileclose(a_bfile); commit; end; select name,content,dbms_lob.getlength(content) from test |
4.把BLOB字段写回到文件中
DECLARE l_file UTL_FILE.FILE_TYPE; l_buffer RAW(32767); l_amount BINARY_INTEGER := 32767; l_pos INTEGER := 1; l_blob BLOB; l_blob_len INTEGER; BEGIN SELECT content INTO l_blob FROM test WHERE name = 'plan.bmp'; l_blob_len := DBMS_LOB.GETLENGTH(l_blob); l_file := UTL_FILE.FOPEN('PIC','planbk.bmp','w', 32767); WHILE l_pos < l_blob_len LOOP DBMS_LOB.READ (l_blob, l_amount, l_pos, l_buffer); UTL_FILE.PUT_RAW(l_file, l_buffer, TRUE); l_pos := l_pos + l_amount; END LOOP; UTL_FILE.FCLOSE(l_file); EXCEPTION WHEN OTHERS THEN IF UTL_FILE.IS_OPEN(l_file) THEN UTL_FILE.FCLOSE(l_file); END IF; RAISE; END; |
5.结果如下:
-
red.bmp 1.2K 写入 BLOB 字段和写入图片文件均正常。
-
other.jpg 17K 写入 BLOB 字段正常,但是写入图片文件失真。
-
Plan.bmp 148K 写入 BLOB 字段正常,写入图片文件报如下错误
ORA-29285: file write error
ORA-06512: at line 31
6.最后在网上找了一下原因如下:
“在 Windows 2000 平台上的 9.2.0 版中出现的特定端口 Bug #2546782 报告了来自 Utl_File.Put_Raw 的错误输出”
结论:
Oracle9i本身提供的数据包对二进制文件和BLOB字段的支持并不好,一些图片文件会失真,而且有读取大小的限制,在Windows2000平台上还存在Bug。据说这些包主要是为了支持flat file用的,并不是以二进制文件为主的。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8128313/viewspace-976135/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/8128313/viewspace-976135/