0

特定の仕様に従うテーブルをエクスポートするために、Oracle 11g データベースの pl/sql に関数を作成しました。これらの詳細の 1 つは \n as break 行です。

PROCEDURE exportTableAScsv (p_tname varchar2) IS
    fileHandler     UTL_FILE.FILE_TYPE;
    l_theCursor     integer default dbms_sql.open_cursor;
    l_columnValue   varchar2(4000);
    l_status        integer;
    l_query         varchar2(1000) default 'select * from ' || p_tname;

    l_colCnt        number := 0;
    l_separator     varchar2(1) default '|';
    l_descTbl       dbms_sql.desc_tab;
    test_n          number:=0;
    filename        varchar2(100) := 'custom_export_'|| p_tname ||'_' ||    to_char(sysdate,'yyyymmddhhmmss')|| '.csv';
    ex_custom EXCEPTION;
    PRAGMA EXCEPTION_INIT( ex_custom, -20001 );

 BEGIN

 fileHandler := UTL_FILE.FOPEN('TEMPDIR', filename , 'W');
 dbms_sql.parse(  l_theCursor,  l_query, dbms_sql.native );
 dbms_sql.describe_columns( l_theCursor, l_colCnt, l_descTbl );
 . . .

 for i in 1 .. l_colCnt loop
     if (i>1) then
         UTL_FILE.put( fileHandler, l_separator || l_descTbl(i).col_name );
     else
         UTL_FILE.put( fileHandler, l_descTbl(i).col_name );
     end if;
     dbms_sql.define_column( l_theCursor, i, l_columnValue, 4000 );
 end loop;
 -- UTL_FILE.put_line(fileHandler,'')
 UTL_FILE.fflush(fileHandler)
 UTL_FILE.put( fileHandler, CHR(10) );

 l_status := dbms_sql.execute(l_theCursor);
 . . . 
 while ( SYS.dbms_sql.fetch_rows(l_theCursor) > 0 ) loop
     for i in 1 .. l_colCnt loop
         SYS.dbms_sql.column_value( l_theCursor, i, l_columnValue );
         if (i > 1) then
            utl_file.put( fileHandler, l_separator || l_columnValue );
         else
            utl_file.put( fileHandler, l_columnValue );
         end if;
     end loop;
    -- UTL_FILE.put_line(fileHandler,'')
    UTL_FILE.fflush(fileHandler)
    UTL_FILE.put( fileHandler, CHR(10) );
  end loop;

  dbms_sql.close_cursor(l_theCursor);
  UTL_FILE.FCLOSE(fileHandler);
EXCEPTION
 . . .
 UTL_FILE.FCLOSE(fileHandler);
 raise;
. . . 
END exportTableAScsv;

タイトルで述べたように、上記のコードにもかかわらず、関数を実行すると、\r\n を行末として Windows 形式として抽出されたデータが常に取得されます。Oracle DB は Windows マシン上にあります。PS残念ながら、Linuxボックスにデータベースを配置して、代わりにput_lineを使用することはできません。

4

1 に答える 1

1

これは、UTL_FILE.FFLUSH の使用が原因であると思われます。ドキュメントから引用するには(私の強調):

FFLUSH は、保留中のデータをファイル ハンドルで識別されるファイルに物理的に書き込みます。通常、ファイルに書き込まれるデータはバッファリングされます。FFLUSH プロシージャは、バッファリングされたデータを強制的にファイルに書き込みます。 データは改行文字で終了する必要があります。

ただし、関数では、 PUT を使用して改行を追加する前にFFLUSH を呼び出しています。Windows ボックスを使用しているため、代わりに Windows の改行文字が表示されます。

余談ですが; なぜこれはプロシージャではなく関数なのですか? 人々がこれをSQLから呼び出せるようにしたくないので、プロシージャとしてより理にかなっています。

于 2013-01-28T15:03:30.513 に答える