2011-11-10 54 views
0

以下存储过程旨在从Oracle数据库中获取所有BLOB值并将其保存到名为OraFolder的文件夹中。我真的需要这个存储过程中的参数吗?

它编译得很好,但我有2个问题。

1,有2个参数,pname和display_name。我必须承认,我不知道他们在那里是什么,因为我只是搜索了似乎符合我们需要的代码。

我的问题是我真的需要2个参数,因为我们试图将所有BLOB值提取到一个文件夹中?

2,如果您的答案是肯定的,我确实需要他们,我该如何使用他们?

最后,有一个Entry_Id,我只是不断收到一个错误,它没有声明。我不得不删除它。它是干什么用的?

Sorr,我不是甲骨文的人,只是试图找出一个WA来解决掉在我圈上的问题。

在此先感谢

这里是完整的存储过程。

create or replace PROCEDURE blob2file(pfname VARCHAR2, display_name in varchar2) IS 



vblob BLOB; 
vstart NUMBER := 1; 
bytelen NUMBER := 32000; 
len NUMBER; 
my_vr RAW(32000); 
x NUMBER; 
v_name varchar2(100); 
lv_str_len NUMBER; 
l_output utl_file.file_type; 



BEGIN 
-- define output directory 
lv_str_len := length(pfname); 
--v_name := display_name||upper(substr(pfname,lv_str_len-3,lv_str_len)); 
v_name := display_name; 
l_output := utl_file.fopen('MY_FOLDER', v_name, 'w', 32760); 



-- get length of blob 
SELECT dbms_lob.getlength(blob_content) 
INTO len 
FROM portal.WWDOC_DOCUMENT$ 
WHERE FILENAME = pfname; 


-- dbms_output.put_line('Length: '||len); 
-- save blob length 
x := len; 



-- select blob into variable 
SELECT blob_content 
INTO vblob 
FROM portal.WWDOC_DOCUMENT$ 
WHERE FILENAME = pfname; 



-- if small enough for a single write 
IF len < 32760 THEN 
-- dbms_output.put_line('Single write '); 
utl_file.put_raw(l_output,vblob); 
utl_file.fflush(l_output); 
ELSE -- write in pieces 
-- dbms_output.put_line('multi write '||vstart); 
vstart := 1; 
WHILE vstart < len 
LOOP 

dbms_lob.read(vblob,bytelen,vstart,my_vr); 



utl_file.put_raw(l_output,my_vr); 
utl_file.fflush(l_output); 



-- set the start position for the next cut 
vstart := vstart + bytelen; 



-- set the end position if less than 32000 bytes 
x := x - bytelen; 
IF x < 32000 THEN 
bytelen := x; 
END IF; 
END LOOP; 
END IF; 
dbms_output.put_line('End'); 
utl_file.fclose(l_output); 
EXCEPTION 
when others then dbms_output.put_line('ERROR:'||entry_id); 
END blob2file; 
+0

我假定这是黑客攻击了一个你得编译。 PL是一种图灵完备的语言,它与基于ADA的其他语言具有相同的规则。请给我看原始的SP,我会看看我能做些什么。 – FlyingGuy

+0

好的,谢谢。我用您请求的原件替换了发布的代码。 – Kenny

回答

0

参数pfname定义了要抓取哪个文件,所以你不需要它,因为你想要它们。

参数display_name定义了输出目录,所以如果你想硬编码目录,你可以。

既然你想要的所有文件,你会通过表并将其输出一个所有记录在一个时间需要循环:

CREATE OR REPLACE PROCEDURE blob2file 
IS 
    l_output utl_file.file_type; 
    vstart  NUMBER := 1; 
    bytelen  NUMBER := 32000; 
    x   NUMBER; 
    my_vr  RAW(32000); 
BEGIN 

    FOR recFiles IN (SELECT dbms_lob.getlength(BLOB_CONTENT) as len, 
          FILENAME, 
          BLOB_CONTENT 
         FROM PORTAL.WWDOC_DOCUMENT$) 
    LOOP 

     l_output := utl_file.fopen('MY_FOLDER', '/hard code the path here/', 'w', 32760); 

     IF recFiles.len < 32760 THEN 

     utl_file.put_raw(l_output, recFiles.BLOB_CONTENT); 
     utl_file.fflush(l_output); 

     ELSE -- write in pieces 

     vstart := 1; 

     WHILE vstart < refFiles.len 
     LOOP 
      dbms_lob.read(recFiles.BLOB_CONTENT, bytelen, vstart, my_vr); 
      utl_file.put_raw(l_output, my_vr); 
      utl_file.fflush(l_output); 

      -- set the start position for the next cut 
      vstart := vstart + bytelen; 

      -- set the end position if less than 32000 bytes 
      x := x - bytelen; 

      IF x < 32000 THEN 
       bytelen := x; 
      END IF; 

     END LOOP; 

     END IF; 

     utl_file.fclose(l_output); 
     dbms_output.put_line('End'); 

EXCEPTION 
    WHEN OTHERS THEN 
     dbms_output.put_line('ERROR: ' || SQLERRM); 

END blob2file; 
+0

非常感谢你专家,我有我的代码版本工作。我能够从数据库中提取几个文件到指定的文件夹。一切看起来不错。但是,在成功提取了2个文件后,每次尝试提取任何其他文件都会导致出现错误,指出“无效的十六进制数”,我无法将此错误包裹在头上。我的目标是确保我的工作正常,然后我会使用wweiker提供的这个很好的解决方案来提取所有的文件,但目前效果不佳。你能帮忙吗? – Kenny

+0

@Kenny你能发布错误详情吗?行号,异常消息...以及错误发生在哪里,在我的代码或原始代码中,还是它们的合并? – wweicker

0

貌似vname是该斑被写入到文件的名称。并且pname是表中blob的关键。所以,如果你在表中倾销所有的斑点,那么你不需要其中任何一个,但是你需要为每个斑点提供一个唯一的文件名。

相关问题