Oracle BLOB - 撤消表空间并高效写入文件

时间:2012-06-04 21:25:51

标签: oracle plsql

请参阅本文末尾的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)中找到的文件名,并将某些文件名提取到BLOBAS_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块。现在,这个过程似乎挂了,所以不确定现在发生的问题......

2 个答案:

答案 0 :(得分:0)

对于LOB段的撤消管理方式与对散列表的正常撤消不同。撤消将作为lob列本身的一部分进行管理和存储。使用pctversion参数,您可以指定为撤消留出多少空间。该值指定为百分比值。

答案 1 :(得分:0)

在DBMS_LOB.READ调用中,l_amount是一个IN OUT参数,每次穿过外部循环时都会越来越小。它可以小到1,在这种情况下,您一次只处理1个字节。在你设置l_pos:= 1之后;还设置l_amount = 32767;