VARCHAR2 są ograniczone do 4000 bajtów. Jeśli pojawi się ten błąd
Wtedy jest całkiem jasne, że konkatenacja przekracza 4000 bajtów.
Co teraz robić?
Twoje pierwsze rozwiązanie polegające na użyciu CLOB jest poprawne.
select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d)
Wygląda na to, że Twoim prawdziwym problemem jest zapisywanie do pliku
Chociaż nie napisałeś, jak zapisać wynikowy clob do pliku, uważam, że nie robisz tego poprawnie. Jeśli próbujesz zapisać do pliku w taki sam sposób, jak robiłeś to z VARCHAR2, robisz to źle.
Musisz najpierw użyć dbms_lob.read
aby odczytać plik z bazy danych, użyj utl_file.put_raw
zapisać do pliku.
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;