VARCHAR2 são limitados a 4000 bytes. Se você receber este erro
Então fica bem claro que a concatenação excede 4000 bytes.
Agora o que fazer?
Sua primeira solução para usar CLOB está correta.
select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d)
Parece que seu problema real é salvar em arquivo
Embora você não tenha postado como salvar o clob resultante em um arquivo, acredito que você não esteja fazendo isso corretamente. Se você tentar salvar no arquivo da mesma forma que estava fazendo com VARCHAR2, você está fazendo errado.
Você precisa primeiro usar
dbms_lob.read
para ler o clob do banco de dados, use utl_file.put_raw
para gravar no arquivo. 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;