请参阅本文末尾的pl / sql代码块
我正在编写一些pl / sql代码来从zip中提取某些文件。我正在使用http://technology.amis.nl/wp-content/uploads/2010/06/as_zip7.txt中的“as_zip”包来获取zip(AS_ZIP.GET_FILE_LIST
)中找到的文件名,并将某些文件名提取到BLOB
(AS_ZIP.GET_FILE
)然后使用UTL_FILE
将文件写入文件。
第一个问题
就我在监控中看到的那样,UNDO TABLESPACE
似乎在这个过程中没有被写入,但我想与其他人确认这是真的...如果我只是提取内容将特定文件转换为BLOB
,然后将其写入文件,UNDO TABLESPACE
会受到影响吗?企业在数据库上使用的每兆字节都要收取费用,因此我们需要始终寻找减少表空间的方法......
第二个问题
在将blob写入文件方面,是否有更有效的方法来完成它然后我是如何做到的?第一个文件(恰好是3.03GB的最大文件)写入文件系统很好而且快速但随后每个后续文件似乎写得越来越慢。我是否需要释放资源或以不同方式分配资源或......
SET SERVEROUTPUT ON
declare
zip_files as_zip.file_list;
l_file UTL_FILE.FILE_TYPE;
L_BUFFER RAW (32767);
L_AMOUNT BINARY_INTEGER := 32767;
l_pos INTEGER;
L_BLOB BLOB;
l_blob_len INTEGER;
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
ZIP_FILES := AS_ZIP.GET_FILE_LIST( 'MY_DIR', 'MY_FILE.zip' );
for i in zip_files.first() .. zip_files.last
LOOP
FOR EXT_TABLE_REC IN (SELECT LOCATION FROM USER_EXTERNAL_LOCATIONS) LOOP
-- Check if there's a match between what's in the zip file and what the external table name is
IF (INSTR(TRIM(LOWER(ZIP_FILES(I))),TRIM(LOWER(EXT_TABLE_REC.LOCATION || '__'))) > 0) THEN
DBMS_OUTPUT.PUT_LINE('Match found on ' || ZIP_FILES(I) || ', ' || EXT_TABLE_REC.LOCATION || ' - processing...');
L_BLOB := AS_ZIP.GET_FILE('MY_DIR', 'MY_FILE.zip', zip_files(i));
-- Open the destination file. Note the third parameter "wb"
l_file := UTL_FILE.FOPEN ('MY_DIR', EXT_TABLE_REC.LOCATION, 'wb');
l_blob_len := DBMS_LOB.getlength (l_blob);
-- Read chunks of the BLOB and write them to the file until complete.
l_pos := 1;
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, FALSE);
l_pos := l_pos + l_amount;
END LOOP;
-- Close the file.
UTL_FILE.FCLOSE (L_FILE);
end if;
end loop;
end loop;
END;
/
如果有人想知道,这是我登录时数据库信息的回复:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, Oracle Label Security,
OLAP, Data Mining, Oracle Database Vault and Real Application Testing options
编辑1
我根据我在Oracle网站上找到的信息取出了EXCEPTION WHEN OTHERS
块。现在,这个过程似乎挂了,所以不确定现在发生的问题......
答案 0 :(得分:0)
对于LOB段的撤消管理方式与对散列表的正常撤消不同。撤消将作为lob列本身的一部分进行管理和存储。使用pctversion参数,您可以指定为撤消留出多少空间。该值指定为百分比值。
答案 1 :(得分:0)
在DBMS_LOB.READ调用中,l_amount是一个IN OUT参数,每次穿过外部循环时都会越来越小。它可以小到1,在这种情况下,您一次只处理1个字节。在你设置l_pos:= 1之后;还设置l_amount = 32767;