VARCHAR2 sont limités à 4000 octets. Si vous obtenez cette erreur
Ensuite, il est assez clair que la concaténation dépasse 4000 octets.
Que faire maintenant ?
Votre première solution pour utiliser CLOB à la place est correcte.
select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d)
Il semble que votre vrai problème soit l'enregistrement dans un fichier
Bien que vous n'ayez pas publié comment enregistrer le clob résultant dans un fichier, je pense que vous ne le faites pas correctement. Si vous essayez d'enregistrer dans un fichier de la même manière que vous le faisiez avec VARCHAR2, vous vous trompez.
Vous devez d'abord utiliser dbms_lob.read
pour lire le clob de la base de données, puis utilisez utl_file.put_raw
pour écrire dans un fichier.
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;