在Oracle 10g中存储Bfile比Blob花费更多时间

时间:2014-02-26 04:44:45

标签: sql oracle procedure

我已编写此程序将文件保存为oracle 10g数据库中的BFILE

create or replace PROCEDURE PROC_NEW_FIN_DETAILS1(S_USER_ID IN VARCHAR2,myfile IN BLOB)
AS

  l_file UTL_FILE.FILE_TYPE;
  FILEPATH VARCHAR2(20):='My_Folder'; 
  l_blob BLOB           :=NULL;
  l_blob_len INTEGER;
  l_pos      INTEGER := 1;
  --MYFILE_NAME VARCHAR2(250):='';
  MODFILENAME VARCHAR2(250):='';
  l_buffer RAW(32767);
  l_amount BINARY_INTEGER := 32767;
  ENTRYCODE VARCHAR2(10)  := '';
  STATUS VARCHAR2(10)  := '1';
  CNT NUMBER :=0;
  DOCUMENT_ID VARCHAR2(20)  := '';

   BEGIN  
    l_blob := myfile;
    l_blob_len := DBMS_LOB.getlength(l_blob);
    l_pos      := 1;

    MODFILENAME := 'test' || '.jpg';

    l_file     := UTL_FILE.fopen(FILEPATH,MODFILENAME,'wb', 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);
    COMMIT;

 INSERT INTO temp_detail(S_DETAIL_ID,S_USER_ID,S_IMAGE,s_file)
VALUES(MY_SEQ.NEXTVAL,S_USER_ID,null,bfilename(FILEPATH,MODFILENAME)); 
    commit;

END PROC_NEW_FIN_DETAILS1;

早期的文件使用此查询

在数据库本身中保存为BLOB
INSERT INTO TEMP_DETAIL(S_DETAIL_ID,S_USER_ID,S_IMAGE,s_file) VALUES (MY_SEQ.NEXTVAL,?,?,?)

Techincally,BFILE应该比BLOB花费更少的时间,但在我的情况下 BFILE比BLOB花费的时间多3倍 这可能是什么原因? 我是编写存储过程的新手,所以请建议我优化这个过程

1 个答案:

答案 0 :(得分:0)

我认为原因可能是错误的定义:你只是比较不同性质的东西。

我们来看看代码吧。检查我的评论,我认为这可能很有用。

-- why do you do that? just use "myfile" instead of l_blob!
l_blob := myfile;

-- takes a bit of time, but of course cannot be avoided
l_blob_len := DBMS_LOB.getlength(l_blob);
l_pos      := 1;

MODFILENAME := 'test' || '.jpg';

l_file     := UTL_FILE.fopen(FILEPATH,MODFILENAME,'wb', 32767);

WHILE l_pos < l_blob_len
LOOP
  -- reading the values from current BLOB, should be quite fast but anyway takes time
  -- multiply this read-write operations execution time on the amount of iterations
  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);
COMMIT;

现在将它与插入的BLOB值进行比较:

INSERT INTO TEMP_DETAIL(S_DETAIL_ID,S_USER_ID,S_IMAGE,s_file) VALUES (MY_SEQ.NEXTVAL,?,?,?);

无。只需插入就是这样。您还应该了解,当您谈论BLOB值时,您会说明定位器,它只是对真实BLOB的引用。这意味着当您插入BLOB时,甚至可以不触摸文件内容本身,例如如果此BLOB已从数据库中获取:see documentation。在这种情况下,参考将仅保存。

当然,我这里只有猜测而且我不是假装100%肯定。但是,至少,你可以检查这些想法。