Select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d)
from table1
上記のクエリは、データをテキスト ファイルに適切にスプールしていません。
一方、
Select a||b||c||d
from table1.
終了しています
行 191 のエラー: ORA-01489: 文字列連結の結果が長すぎます。
助けてください !!!
VARCHAR2 は 4000 バイトに制限されています。このエラーが発生した場合
行 191 のエラー: ORA-01489: 文字列連結の結果が長すぎます。
次に、連結が 4000 バイトを超えていることは明らかです。
今何をすべきか?
代わりに CLOB を使用する最初のソリューションは正しいです。
select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d)
あなたの本当の問題はファイルに保存しているようです
上記のクエリは、データをテキスト ファイルに適切にスプールしていません。
結果の clob をファイルに保存する方法を投稿していませんが、正しく行っていないと思います。VARCHAR2 で行っていたのと同じ方法でファイルに保存しようとすると、間違っています。
最初に使用dbms_lob.read
してデータベースから clob を読み取り、次に使用utl_file.put_raw
してファイルに書き込む必要があります。
DECLARE
position NUMBER := 1;
byte_length NUMBER := 32760;
length NUMBER;
vblob BLOB;
rawlob RAW(32760);
temp NUMBER;
output utl_file.file_type;
BEGIN
-- Last parameter is maximum number of bytes returned.
-- wb stands for write byte mode
output := utl_file.fopen('DIR', 'filename', 'wb', 32760);
position := 1;
select dbms_lob.getlength(yourLob)
into len
from somewhere
where something;
temp := length;
select yourLob
into vlob
from somewhere
where something;
IF len < 32760 THEN
utl_file.put_raw(output, vblob);
-- Don't forget to flush
utl_file.fflush(output);
ELSE -- write part by part
WHILE position < len AND byte_length > 0
LOOP
dbms_lob.read(vblob, byte_length, position, rawlob);
utl_file.put_raw(output,rawlob);
-- You must admit, you would have forgot to flush.
utl_file.fflush(output);
position := position + byte_length;
-- set the end position if less than 32000 bytes
temp := temp - bytelen;
IF temp < 32760 THEN
byte_length := temp;
END IF;
END IF;
END;
LONG の値を増やしてみてはどうでしょうか。long 変数をより高い値に増やす必要がある場合があります。詳細な説明については、ここをクリックしてください。
例:
SET LONG 100000;
SPOOL test_clob.txt
SELECT to_clob(lpad('A',4000,'A'))
||'B'
||to_clob(lpad('C',4000,'C'))
||'D'
||to_clob(lpad('E',4000,'E'))
||'F'
FROM dual;
SPOOL OFF;
2 番目のクエリはエラーを返します。クエリの concat(||) 演算子が varchar2 を返そうとしているため、4000 文字の制限があり、それを超えています。
CLOB を表示するときの SQL*Plus ハードコードの行サイズは 81 で、これを回避する方法はないようです。したがって、他のデータベースにロードする csv ファイルを生成する場合、これらの余分な改行を解析するという問題が発生します。
最終的な解決策は、PL/SQL を使用することです。たとえば、テーブル「xyz」からコンマ区切りの csv ファイルを生成するには、次のコードを使用します。
set lin 32766
set serveroutput on size unlimited
DECLARE
TYPE arraytable IS TABLE OF xyz%ROWTYPE;
myarray arraytable;
CURSOR c IS
select * from xyz ;
BEGIN
OPEN c;
LOOP
FETCH c BULK COLLECT INTO myarray LIMIT 10000;
FOR i IN 1 .. myarray.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE(
myarray(i).col1||','||
myarray(i).col2||','||
myarray(i).col3||','||
myarray(i).col4;
END LOOP;
EXIT WHEN c%NOTFOUND;
END LOOP;
END;
/
このアプローチのボーナスは、これが LONG データ型でも機能することです!
xmlagg 関数を試してください。同様の問題に遭遇したとき、それは私にとってはうまくいきました。
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions215.htm