5

大量のデータを CSV ファイルに返すクエリがあります。実際、行が多すぎて Excel で開くことができません。spool65000 行が処理されるたびに新しいファイルにスプールするように制御する方法はありますか? 理想的には、、、、などlarge_data_1.csvの順番で名前が付けられたファイルに出力したいと思います...large_data_2.csvlarge_data_3.csv

PL/SQL ブロックで使用して、出力される行数を制御できますが、PL/SQL ブロックからアクセスできないように見えるためdbms_output、ファイルを切り替えるにはどうすればよいでしょうか?spool

(オラクル 10g)

アップデート:

サーバーへのアクセス権がないため、サーバーへのファイルの書き込みはおそらく機能しません。

更新 2:

一部のフィールドには改行を含む自由形式のテキストが含まれているため、ファイルが書き込まれた後に改行を数えることは、データが返されている間にレコードを数えることほど簡単ではありません...

4

6 に答える 6

9

解決策を見つけました。なぜこれをもっと早く思いつかなかったのかわかりません...

基本的な考え方は、マスター sqplplus スクリプトが、出力を複数のファイルに分割する中間スクリプトを生成するというものです。中間スクリプトを実行すると、さまざまな範囲が課された複数のクエリが実行されrownum、クエリごとに異なるファイルにスプールされます。

set termout off
set serveroutput on
set echo off
set feedback off
variable v_rowCount number;
spool intermediate_file.sql
declare
     i number := 0;
     v_fileNum number := 1;
     v_range_start number := 1;
     v_range_end number := 1;
     k_max_rows constant number := 65536;
begin
    dbms_output.enable(10000);
    select count(*) 
    into :v_err_count
    from ...
    /* You don't need to see the details of the query... */

    while i <= :v_err_count loop

          v_range_start := i+1;
          if v_range_start <= :v_err_count then
            i := i+k_max_rows;
            v_range_end := i;

            dbms_output.put_line('set colsep ,  
set pagesize 0
set trimspool on 
set headsep off
set feedback off
set echo off
set termout off
set linesize 4000
spool large_data_file_'||v_fileNum||'.csv
select data_string
from (select rownum rn, data_object
      from 
      /* Details of query omitted */
     )
where rn >= '||v_range_start||' and rn <= '||v_range_end||';
spool off');
          v_fileNum := v_fileNum +1;
         end if;
    end loop;
end;
/
spool off
prompt     executing intermediate file
@intermediate_file.sql;
set serveroutput off
于 2010-04-13T18:42:37.317 に答える
4

純粋な SQL*Plus ソリューションでこれを試してください...

set pagesize 0
set trimspool on  
set headsep off 
set feedback off
set echo off 
set verify off
set timing off
set linesize 4000

DEFINE rows_per_file = 50


-- Create an sql file that will create the individual result files
SET DEFINE OFF

SPOOL c:\temp\generate_one.sql

PROMPT COLUMN which_dynamic NEW_VALUE dynamic_filename
PROMPT

PROMPT SELECT 'c:\temp\run_#'||TO_CHAR( &1, 'fm000' )||'_result.txt' which_dynamic FROM dual
PROMPT /

PROMPT SPOOL &dynamic_filename

PROMPT SELECT *
PROMPT   FROM ( SELECT a.*, rownum rnum
PROMPT            FROM ( SELECT object_id FROM all_objects ORDER BY object_id ) a
PROMPT           WHERE rownum <= ( &2 * 50 ) )
PROMPT  WHERE rnum >= ( ( &3 - 1 ) * 50 ) + 1
PROMPT /

PROMPT SPOOL OFF

SPOOL OFF

SET DEFINE &


-- Define variable to hold number of rows
-- returned by the query
COLUMN num_rows NEW_VALUE v_num_rows

-- Find out how many rows there are to be
SELECT COUNT(*) num_rows
  FROM ( SELECT LEVEL num_files FROM dual CONNECT BY LEVEL <= 120 );


-- Create a master file with the correct number of sql files
SPOOL c:\temp\run_all.sql

SELECT '@c:\temp\generate_one.sql '||TO_CHAR( num_files )
                                   ||' '||TO_CHAR( num_files )
                                   ||' '||TO_CHAR( num_files ) file_name
  FROM ( SELECT LEVEL num_files 
           FROM dual 
        CONNECT BY LEVEL <= CEIL( &v_num_rows / &rows_per_file ) )
/

SPOOL OFF

-- Now run them all
@c:\temp\run_all.sql
于 2010-04-14T07:48:43.950 に答える
1

結果のファイルで分割を使用します。

于 2010-04-13T14:09:04.697 に答える
0

utl_file探しているパッケージです。カーソルを書き込み、行をループして (それらを書き出す) mod(num_rows_written,num_per_file) == 0、新しいファイルを開始するときに行うことができます。PL/SQL ブロック内で問題なく動作します。

のリファレンスは次のutl_fileとおりです 。 http://www.adp-gmbh.ch/ora/plsql/utl_file.html

注: ここでは、ファイルをサーバーに書き込んでも問題ないと仮定しています。

于 2010-04-13T14:00:20.973 に答える
0

Excel での外部データ接続の設定を検討しましたか (CSV ファイルは Excel で使用するためだけに作成されていると仮定します)。返される行を制限する Oracle ビューを定義し、クエリにいくつかのパラメーターを追加して、ユーザーが結果セットをさらに制限できるようにすることもできます。(とにかく、誰かが Excel で 64K 行を使用して何をしているのか理解できませんでした)。

これはハックのように感じますが、UTL_MAIL を使用して添付ファイルを生成し、ユーザーに電子メールで送信することもできます。添付ファイルには 32K のサイズ制限があるため、カーソル ループ内のサイズを追跡し、これに基づいて新しい添付ファイルを開始する必要があります。

于 2010-04-13T15:06:32.570 に答える
0

あなたの質問は、膨大な量のデータをExcelが処理できるチャンクに分割する方法を尋ねていますが、データ量を減らすことができるSQL(PL / SQL?)に移動できるExcel操作の部分があるかどうかを尋ねます。最終的には、誰にとっても意味のあるものにするには、削減する必要があります。データベースは、その作業を行うための優れたエンジンです。

データをより見栄えのするボリュームまたは最終結果にまで縮小したら、それを Excel 用にダンプして、最終的なプレゼンテーションを作成します。

これはあなたが探していた答えではありませんが、仕事をやり遂げるのが難しくなってきたら、適切なツールを使用しているかどうかを尋ねることは常に良いことだと思います.

于 2012-05-07T19:49:51.427 に答える