2011-11-14 26 views
0

私は今朝、この問題を抱えています。私は実際にここでこのコードを見て、私たちの目的のためにここで使うことにしました。"数値または値のエラー"メッセージを修正するにはどうすればよいですか?

私が実行している問題は、コードを実行すると、dbからそのファイルをフォルダーに書き込むことがあることです。

他の回、私たちは

「を数値または値のエラー」を取得する任意の専門家は、私はそれを修正する助けてくださいことはできますか?

create or replace 
PROCEDURE getfile(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(32760); 
    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_DIR', v_name, 'w', 32760); 

    -- get length of blob 
    SELECT dbms_lob.Getlength(FILENAME) 
    INTO len 
    FROM GENERAL.GUBFILE 
    WHERE gubfile_name = pfname; 

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

    -- select blob into variable 
    SELECT BLOBVALUE 
    INTO vblob 
    FROM FILES 
    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); 
END getfile; 

正確なエラーは次のとおりです:

ORA-06502:PL/SQL:数値または値のエラー ORA-06512:「USER.GETFILEでここ

は、私が使用していたコードです"、line 40 ORA-06512:at line 8

答えて

2

エラーはutl_file.put_rawに由来します。 バッファパラメータの最大サイズは32767バイトです。あなたがIF len < 32760 THENをチェック

は、しかし、私はlen変数が実際にput_rawコールでのバッファであるvblob変数の長さを保持していることを、あなたのコード内で保証を参照してくださいません。

したがって、vblob変数の実際の長さは32767より長く、エラーの原因と思われます。

そこで私は、コードのこの部分を削除することをお勧め:

IF len < 32760 THEN 
    -- dbms_output.put_line('Single write '); 
    utl_file.Put_raw(l_output, vblob); 

    utl_file.Fflush(l_output); 
    ELSE 

もちろんのEND IF;、と常にブランチ「の部分で書き込み」のために行きます。

私が今見る、あなたと違って、バールソンが同じテーブルと同じフィールドからLEN変数とvblob変数を取得し、

http://www.dba-oracle.com/t_writing_blob_clob_os_file.htm良いのですが、あなたが見るバーレソン例に基づいてこれをやりました。

​​

EDIT

だから、他のオプションは、長さを取得するための選択を修正することです。

-- get length of blob 
    SELECT dbms_lob.Getlength(FILENAME) 
    INTO len 
    FROM GENERAL.GUBFILE 
    WHERE gubfile_name = pfname; 

これで:

-- get length of blob 
    SELECT dbms_lob.Getlength(BLOBVALUE) 
    INTO len 
    FROM FILES 
    WHERE filename = pfname; 
+0

Fanstatic説明これは、あなたがこの選択を交換する必要がありますを意味します!どうもありがとうございました。私はselect ... filenameから選択を変更しました... blobvalueとうまくいきました!あなたはどこで私を助けてくれますか?この方法で、すべてのファイルを一度に取得できますか? –

+0

@Chidi、素晴らしいフィードバックのおかげで!この問題が解決した場合は、このスレッドを閉じることを真剣にお勧めします。新しい要求を追加することによって、スレッドの大きな面倒なスパゲッティを作ることは、SOの原則にはっきりと反対しています。 複数のブロブをファイルに書き込む場合は、カーソルを開いて、カーソルによって返されるすべてのファイル名/表示名のペアに対してこのプロシージャをコールする必要があります。ちょっとしたヒントがあります。そうしないといけない場合は、新しい投稿で助けを求めてください。 'for c in(FILESからファイル名を選択)ループ getfile(c.filename、c.filename || '.txt'); 終了ループ; ' – bpgergo

+0

大変申し訳ありません。私は今それを閉じます。 –

関連する問題