pl/sql応用の利用utl_ファイルを書く


前回はpl/sqlを利用してファイルを読む(簡単)編を書きましたが、もしよく分かりませんでした.ファイルはどう読みますか?前回のブログを参考にして、今日はどうやって使うかを書きます.ファイルを書くには、まず私が参考にした文章のリンクを持ちます.
    
http://stackoverflow.com/questions/3750192/how-to-write-to-files-using-utl-file-in-oracle
http://blog.csdn.net/liqfyiyi/article/details/7043942
http://qingyujingyu427.iteye.com/blog/402151
http://www.morganslibrary.org/hci/hci004.html
    無駄話は多く言わないで、コードを付けます.
   
declare
  fHandle UTL_FILE.FILE_TYPE;
begin
 --         
  fHandle := UTL_FILE.FOPEN('ORADIR_F_DIR', 'test_write_file.sql', 'w');
  UTL_FILE.PUT(fHandle, '    ');
  UTL_FILE.PUT(fHandle, '  \r
'); UTL_FILE.PUT_LINE(fHandle,''); -- : chr(10) UTL_FILE.PUT(fHandle, ' '||chr(10)||' '); -- : chr(13) UTL_FILE.PUT(fHandle, ' '||chr(13)||' '); -- : PUT_LINE UTL_FILE.PUT_LINE(fHandle, ' '); UTL_FILE.PUT_LINE(fHandle, ' '||chr(9)||' '); -- UTL_FILE.NEW_LINE(fHandle,1); UTL_FILE.PUT(fHandle, ' '); UTL_FILE.FCLOSE(fHandle); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Exception: SQLCODE=' || SQLCODE || ' SQLERRM=' || SQLERRM); RAISE; end;
   運転結果は以下の通りです.
   pl/sql应用之利用utl_file写文件_第1张图片     説明下:ORADIR_F_DIRはカタログです.ディレクトリを作るには私のブログ番号pl/sqlを利用してファイルを読む(簡単)を参照してください.ファイル名は中国語ではできません.fopenの最後のパラメータはよく使われています.r読みw書き込みaは読み取り専用のバイトwbを追加します.ファイルを上書きしたくないなら、a(追加)を使ってください.他のコードにはっきり書いてください.
      utl_fileはファイルを書くのによくある機能はログを記録するので、個人もutl_を使うことを勧めます.fileログ:
     
declare
  fHandle UTL_FILE.FILE_TYPE;
  v_out number(3);
begin
  --w   
  fHandle := UTL_FILE.FOPEN('ORADIR_F_DIR', 'syslog_'||to_char(sysdate,'yyyy_mm_dd')||'.log', 'a');
  UTL_FILE.put_line(fHandle,'      ');
  v_out:=1/0;
  UTL_FILE.FCLOSE(fHandle);
EXCEPTION
  WHEN OTHERS THEN
    IF utl_file.is_open(fHandle) THEN
    utl_file.PUT_LINE(fHandle,'Exception: SQLCODE=' || SQLCODE || '  SQLERRM=' ||
                         SQLERRM);
    utl_file.fclose(fHandle);
  END IF;
   RAISE;
end;
   結果:
   pl/sql应用之利用utl_file写文件_第2张图片    ファイルを書くのはログファイルだけではなく、データベースの中のclob.blobまたは照会結果をxml、jpg、xls、cvsなどの拡張子のファイルに出力することもできます.以下のように例を挙げて説明します.
    (一)clobをlogファイルとして出力する
   
create or replace procedure proc_write_clob_demo(id number) IS
  sql_stmt   VARCHAR2(100);
  l_content  clob;
  l_fHandler UTL_FILE.FILE_TYPE;
BEGIN
  sql_stmt := 'select content from t_blob_test where id=:id';
  EXECUTE IMMEDIATE sql_stmt
    into l_content
    using id;
   dbms_xslprocessor.clob2file(l_content,'ORADIR_F_DIR','writeclob_'||id||'.log');
  UTL_FILE.FCLOSE(l_fHandler);
EXCEPTION
  WHEN OTHERS THEN
    IF UTL_FILE.IS_OPEN(l_fHandler) THEN
      UTL_FILE.FCLOSE(l_fHandler);
    END IF;
    DBMS_OUTPUT.PUT_LINE('Exception: SQLCODE=' || SQLCODE || '  SQLERRM=' ||
                         SQLERRM);
    RAISE;
END;
   テスト方法:
  
call proc_write_clob_demo(148)
    結果:
   pl/sql应用之利用utl_file写文件_第3张图片    ここで説明します.dbms_を使います.xsloprocessor.clob 2 file出力clobフィールドがlogファイルの場合、個人テスト出力のlogファイルは1 Mで、出力時間は1.8 sです.個人的にはスピードが速い方法があるはずです.知っている友達に教えてください.
    (二)出力clobはxmlファイルです.
    ここで注意してください.clobの中に入っているのはxmlファイルか、それともXMLTタイプのものですか?他のものはだめです.
   
CREATE OR REPLACE PROCEDURE proc_write_xml_demo (id number) IS
  xml_str            clob;
  xml_file           Utl_File.file_type;
  offset             NUMBER              := 1;
  buffer             varchar2(32767);
  buffer_size        number              := 2000;
begin
  xml_file := utl_file.fopen('ORADIR_F_DIR','writexml_demo.xml','w');
  xml_str := DBMS_XMLGEN.getXML('select content from xmltype_table where id='||id);
  while(offset < dbms_lob.getlength(xml_str))
  loop
     buffer := dbms_lob.substr(xml_str,buffer_size,offset);
     utl_file.put(xml_file,buffer);
     utl_file.fflush(xml_file);
     offset := offset + buffer_size;
  end loop;
  utl_file.fclose(xml_file);
  dbms_lob.freetemporary(xml_str);
end;
 
   テスト方法は:
   
call proc_write_xml_demo(4)
    結果:
    pl/sql应用之利用utl_file写文件_第4张图片    (三)出力blobはimgである.
   
CREATE OR REPLACE PROCEDURE PROC_GET_PIC_BLOB (i_xh VARCHAR2) IS
l_file UTL_FILE.FILE_TYPE;
l_buffer RAW(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_blob BLOB;
l_blob_len INTEGER;
BEGIN
SELECT image INTO L_BLOB FROM BXXX WHERE id = i_xh;
 l_blob_len := DBMS_LOB.GETLENGTH(l_blob);
 l_file := UTL_FILE.FOPEN('ORADIR_F_DIR',i_xh || '.jpg','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);
EXCEPTION
 WHEN NO_DATA_FOUND THEN
  DBMS_OUTPUT.put_line('no data : ' || i_xh);
 WHEN OTHERS THEN
  IF UTL_FILE.IS_OPEN(l_file) THEN
   UTL_FILE.FCLOSE(l_file);
  RAISE;
  END IF;
END PROC_GET_PIC_BLOB;
 
   テスト方法は:
   
select * from bxxx
call PROC_GET_PIC_BLOB(2)
   結果:
   pl/sql应用之利用utl_file写文件_第5张图片   (四)出力select結果はcvsファイルです.
    
create or replace procedure proc_write_cvs_demo as
  v_file   UTL_FILE.FILE_TYPE;
  v_buffer VARCHAR2(100);
begin
  v_file   := UTL_FILE.FOPEN('ORADIR_F_DIR',
                             'cvsfile' || to_char(sysdate, 'yyyy_mm_dd') ||
                             '.csv',
                             'w',
                             32767);
  v_buffer := '    ,  ,  ,  ,    ,  ,  ';
  UTL_FILE.PUT_LINE(v_file, v_buffer);
  for v in (select '"' || empno || '","' || ename || '","' || job || '","' || mgr ||
                   '","' || to_char(hiredate, 'yyyy-mm-dd') || '","' || sale ||
                   '","' || deptno || '" ' result
              from emp) loop
   UTL_FILE.PUT_LINE(v_file, v.result);
  end loop;
  UTL_FILE.FCLOSE(v_file);
exception
  when others then
    DBMS_OUTPUT.PUT_LINE('Exception: SQLCODE=' || SQLCODE || '  SQLERRM=' ||
                         SQLERRM);
    RAISE;
end;
   テスト方法は:
  
call proc_write_cvs_demo()
  結果:
  pl/sql应用之利用utl_file写文件_第6张图片     (五)出力select結果はxlsファイルです.
    
create or replace procedure proc_write_xls_demo as
  v_file     UTL_FILE.FILE_TYPE;
  v_buffer   varchar2(100);
  type type_emp is record(
    empno    varchar2(15),
    ename    varchar2(30),
    job      varchar2(15),
    mgr      varchar2(10),
    hiredate varchar2(12),
    sale     varchar2(10),
    deptno   varchar2(10));
  type_empinfo type_emp;
  cursor cur_emp is
    select empno||chr(9),
           ename||chr(9),
           job||chr(9),
           mgr||chr(9),
           to_char(hiredate, 'yyyy-mm-dd')||chr(9),
           sale||chr(9),
           deptno
      from emp
     where rownum <= 10;
begin
--oracle   excel       chr(9)               excel  
  v_buffer:='    '||chr(9)||'  '||chr(9)||'  '||chr(9)||'  '||chr(9)||'    '||chr(9)||'  '||chr(9)||'  ';
  v_file     := UTL_FILE.FOPEN('ORADIR_F_DIR', 'xlsfile' || to_char(sysdate, 'yyyy_mm_dd')||'.xls', 'w', 32767);
  utl_file.put_line(v_file, v_buffer);
  open cur_emp;
  loop
    fetch cur_emp
      into type_empinfo;
    exit when cur_emp%notfound;
    utl_file.put(v_file, type_empinfo.empno);
    utl_file.put(v_file, type_empinfo.ename);
    utl_file.put(v_file, type_empinfo.job);
    utl_file.put(v_file, type_empinfo.mgr);
    utl_file.put(v_file, type_empinfo.hiredate);
    utl_file.put(v_file, type_empinfo.sale);
    utl_file.put_line(v_file, type_empinfo.deptno);
    -- utl_file.new_line(v_file,1);
    --       
    --utl_file.fflush(v_file);
  end loop;
  utl_file.fclose(v_file);
  close cur_emp;
exception
  when others then
    DBMS_OUTPUT.PUT_LINE('Exception: SQLCODE=' || SQLCODE || '  SQLERRM=' ||
                         SQLERRM);
    RAISE;
end;
   テスト方法は:
  
call proc_write_xls_demo()
    結果:
    pl/sql应用之利用utl_file写文件_第7张图片    ブログは簡単に紹介しただけです.どのように出力してファイルに出力するかは、utl_fileの他の使い方についてはコピーやファイルの属性などは紹介されていません.興味のある方は詳しく検索してください.
    文章はここに書いても終わります.本文はオリジナルです.転載は出典を明記してください.本文に対して異なる意見があります.メッセージをお願いします.ありがとうございます.