Tôi khá chắc rằng bạn không nên tìm nạp tất cả BLOB vào một mảng khi bắt đầu quy trình. Vì bạn đọc dữ liệu BLOB và không bao giờ thực sự đóng bất kỳ bộ định vị lob nào, nên Oracle phải giữ tất cả thông tin này trong bộ nhớ. Tôi đoán đây là trường hợp quá tải bộ nhớ.
Hãy thử cái này thay thế:
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;