プロシージャの開始時にすべてのBLOBを配列にフェッチするべきではないと確信しています。 BLOBデータを読み取り、実際にLOBロケーターを閉じることはないため、Oracleはこのすべての情報をメモリに保持する必要があります。これはメモリがいっぱいになった場合だと思います。
代わりにこれを試してください:
CURSOR cc IS (SELECT ...)
BEGIN
OPEN cc;
LOOP
FETCH cc
INTO l_fname, l_blob;
EXIT WHEN cc%NOTFOUND;
l_blob_len := DBMS_LOB.getlength(l_blob);
DBMS_OUTPUT.PUT_LINE(l_blob_len);
l_file := UTL_FILE.fopen('BLOBS', l_x || '_' || l_fname, 'w', 32767);
l_pos := 1;
l_x := l_x + 1;
WHILE l_pos < l_blob_len LOOP
DBMS_LOB.READ(l_blob, l_amount, l_pos, l_buffer);
UTL_FILE.put_raw(l_file, l_buffer, TRUE);
l_pos := l_pos + l_amount;
END LOOP;
UTL_FILE.fclose(l_file);
END LOOP;
CLOSE cc;
END;