Я определенно искал FAR и WIDE для ответа на этот вопрос, но я ничего не могу найти! Я использую сценарий UTL_FILE, чтобы вытащить некоторый файл BLOBS из таблицы Oracle и сохранить их в каталоге файлов. Он работает для большого количества файлов, но я сузил его по мере устранения, что у него возникают проблемы с файлами с «нетрадиционным» именем файла, хотя и все еще действительным, файлы становятся поврежденными в передаче. Первоначально они могут быть 30kb, но экспортируются как 5kb и не могут быть открыты. Поэтому я знаю, что это не проблема большого размера файла. Файлы открываются просто в приложении, имеют допустимую кодировку MIME и в противном случае открываются нормально в файловой системе, но UTL_FILE, похоже, не нравится. Это файлы с дополнительным "." в них: john.smith.doc или знак фунта, т. е.: Smith # 12345.doc или круглые скобки и т. д. Я не могу изменить имена исходных файлов в таблице Oracle, но я связывал с ними идентификационный номер, когда сохраняя их, поэтому я могу ссылаться на него как на ключ для загрузки ETL в таблицу файлов SQL позже. Возможно, мне также нужно написать сложный REGEXP, чтобы переименовать файлы на лету и вычеркнуть плохие символы, но я не уверен, что это сработает, потому что я не знаю, в какой момент UTL_FILE задыхается от них. Если это у источника, то это не поможет. Кто-нибудь еще столкнулся с этой проблемой? Вот мой сценарий:Коррекция файлов с помощью скрипта UTL_FILE
DECLARE
CURSOR C1 IS Select FILE_ID || '---' || substr(DOCUMENTLOCATION,1,instr
(DOCUMENTLOCATION,'.')-1)||'.doc' as FILE_NAME, FILE_BLOB, FILE_ID
From DOCUMENTS d inner join CASEJOURNAL c on d.FILE_ID = c.JOURNALENTRYID
where (JOURNAL_ENTRY_TYPE = 117 or JOURNAL_ENTRY_TYPE = 3) AND
c.DOCUMENTLOCATION Is Not Null AND d.MIME_TYPE = 'application/msword'
AND FILE_ID BETWEEN 785 AND 3380;
l_file UTL_FILE.FILE_TYPE;
l_buffer RAW(32000);
l_amount INTEGER := 32000;
l_pos INTEGER := 1;
l_blob BLOB;
l_blob_len INTEGER;
l_filename varchar2(255);
BEGIN
--Select BLOB file into variables
FOR I in C1
LOOP
Select FILE_ID || '---' || substr(DOCUMENTLOCATION,1,instr
(DOCUMENTLOCATION,'.')-1) ||'.doc' as FILE_NAME, FILE_BLOB INTO l_filename,
l_blob From DOCUMENTS d inner join CASEJOURNAL c on d.FILE_ID =
c.JOURNALENTRYID where (JOURNAL_ENTRY_TYPE = 117 or JOURNAL_ENTRY_TYPE =
3) AND c.DOCUMENTLOCATION Is Not Null AND d.MIME_TYPE
= 'application/msword' and d.FILE_ID = I.FILE_ID;
-- Define the output directory
l_file := UTL_FILE.FOPEN('\\myfiledirectory',l_filename,'wb',32000);
l_pos := 1;
l_amount := 32000;
--Get length of BLOB file and save to variable.
l_blob_len := DBMS_LOB.getlength(l_blob);
-- Write the data to the file
--If small enough for single write:
IF l_blob_len < 32000 THEN
UTL_FILE.PUT_RAW (l_file, l_blob);
UTL_FILE.FFLUSH(l_file);
--Write in pieces if larger than 32k
ELSE
l_pos := 1;
WHILE l_pos < l_blob_len AND l_amount > 0
LOOP
DBMS_LOB.read(l_blob, l_amount, l_pos, l_buffer);
UTL_FILE.PUT_RAW(l_file, l_buffer);
UTL_FILE.FFLUSH(l_file);
--Set start position for next write
l_pos := l_pos + l_amount;
--Set end position if less than 32k.
l_blob_len := l_blob_len - l_amount;
IF l_blob_len < 32000 THEN
l_amount := l_blob_len;
END IF;
END LOOP;
END IF;
UTL_FILE.FCLOSE(l_file);
END LOOP;
END;
UPDATE - я обнаружил, что файлы, которые были повреждены при выписке не имеют ничего общего с моим сценарием, ни с именованием они имели в БДЕ. Это связано с тем, что приложение переднего плана сжимало некоторые файлы при загрузке в БД. Невозможно было сказать, какие были сжаты, а какие нет (в БД нет никакого флага). Однако, когда я применил UTL_FILE_COMPRESS.lz_uncompress() к файлам, которые причиняли мне проблемы, они отлично открылись - очевидно. – kharvey