这里比较推荐第一种方式,便于数据及文件管理,方便导入导出,缺点是容易造成数据与文件内容不一致,文件管理与ORACLE关系不大。
重点说一下第二种方式即BLOB\CLOB方式,对于内容不大的可直接存取BLOB,太大的文件借助目录文件。
reate or replace procedure TEST_BLOB_INS (FBuffer IN VARChAR2) IS
DEST_LOB BLOB
WRITE_AMOUNT INTEGER
BEGIN
--FILE_CONTENT为指定大字段
UPDATE XXTABLE SET FILE_CONTENT=EMPTY_BLOB() WHERE ID= 999
SELECT FILE_CONTENT INTO DEST_LOB FROM XXTABLE WHERE ID = 999 FOR UPDATE
DBMS_LOB.OPEN(DEST_LOB,DBMS_LOB.LOB_READWRITE)
WRITE_AMOUNT := LENGTHB(WR_BUFFER)
DBMS_LOB.WRITE(DEST_LOB, WRITE_AMOUNT, 1, UTL_RAW.cast_to_raw(WR_BUFFER))
DBMS_LOB.CLOSE(DEST_LOB)
COMMIT
END TEST_BLOB
借助目录方式在存取:
具体过程:
A,首先请DBA在控制台创建目录记录
CREATE OR REPLACE DIRECTORY MY_DIR as '/home/jsp';
-- 可使用 select * from dba_directories 进行查询是否创建成功;
B,再将新建的MY_DIR目录别名授权给指定用户使用
GRANT READ,WRITE on DIRECTORY MY_DIR TO user_cms
C,将拟存入数据库的文件上传至服务器的/home/jsp目录下
D,再使用以下过程进行文件读出并写入数据库, FName 为文件名, RecID为指定表记录的ID
create or replace procedure TEST_BLOB_FILEINS(RECID IN INTEGER,FName IN VARCHAR2) IS
DEST_LOB BLOB
V_FILE BFILE
V_Fsize INTEGER
BEGIN
V_FILE := BFILENAME('MY_DIR', FName)
UPDATE xxTAble SET FILE_CONTENT=EMPTY_BLOB() WHERE ID= RECID RETURN FILE_CONTENT INTO DEST_LOB
v_FSize := DBMS_LOB.GETLENGTH(v_file)
DBMS_OUTPUT.PUT_LINE('File size: ' || v_Fsize)
DBMS_LOB.FILEOPEN(V_FILE)
DBMS_LOB.LOADFROMFILE(DEST_LOB, V_FILE, DBMS_LOB.LOBMAXSIZE)
DBMS_LOB.FILECLOSEALL
COMMIT
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('在更新BLOB内容时不成功,ID=' || RECID )
END TEST_BLOB
数据提取过程
create or replace procedure download_blob(srcname varchar2, dstname varchar2) as
mount binary_integer := 32767
fbuffer raw(32767)
utlfile utl_file.file_type
dumpfile blob
pos integer := 1
len binary_integer
begin
select blob_file into dumpfile from blob_tb where data_name = srcname
len := dbms_lob.getlength(dumpfile)
utlfile := utl_file.fopen('MY_DIR', dstname, 'wb', 32767)
while pos <len loop
dbms_lob.read(dumpfile, mount, pos, fbuffer)
utl_file.put_raw(utlfile, fbuffer, true)
pos := pos + mount
end loop
utl_file.fclose(utlfile)
end
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)