2013-11-20 2 views
1

Я пишу некоторые pl/sql для генерации отчетов в формате PDF, которые хранятся как капли в таблице оракула. Мне нужно пройти через эту таблицу, в которой есть столбец для имени файла и blob, и записать blob в ОС в виде файла с соответствующим именем файла в таблице. Я довольно много завершил этот код, но я бег в обманка:ORACLE BLOB к файлу

ORA-06550: line 13, column 59: 
PL/SQL: ORA-00904: "SIMS_PROD"."PUBLISH_RPT_NEW"."RPT_FILE_NAME": invalid identifier 
ORA-06550: line 13, column 12: 
PL/SQL: SQL Statement ignored 
06550. 00000 - "line %s, column %s:\n%s" 
Cause: Usually a PL/SQL compilation error. 
Action: 

я прочитал пост на сайте: How can I extract files from an Oracle BLOB field? - однако, - это только для одного файла - моя таблица содержит сотни строк каждый, который имеет blob и связанное с ним имя файла - это цикл через эту таблицу, которая дает мне печаль.

Мне нужно указать имя схемы, таблицу и столбец явно, так как я зарегистрирован как пользователь базы данных DBA, а не как владелец самой схемы. Вот мой код - что мне здесь не хватает или что-то не так. Заранее спасибо за любую помощь со стороны сообщества - ее очень ценят.

DECLARE 
t_blob BLOB; 
t_len NUMBER; 
t_file_name VARCHAR2(100); 
t_output utl_file.file_type; 
t_totalsize NUMBER; 
t_position NUMBER := 1; 
t_chucklen NUMBER := 4096; 
t_chuck RAW(4096); 
t_remain NUMBER; 

BEGIN 
    FOR X IN (SELECT SIMS_PROD.publish_rpt_new.RPT_FILE_NAME,  SIMS_PROD.publish_rpt_new.RPT_CONTENTS FROM SIMS_PROD.PUBLISH_RPT) 

    LOOP 
    -- Get length of blob 
    SELECT dbms_lob.Getlength (SIMS_PROD.publish_rpt_new.RPT_CONTENTS),  SIMS_PROD.publish_rpt_new.RPT_FILE_NAME INTO t_totalsize, t_file_name FROM  SIMS_PROD.publish_rpt_new; 
    t_remain := t_totalsize; 

    -- The directory TEMPDIR should exist before executing 
    t_output := utl_file.Fopen ('PDF_REP', t_file_name, 'wb', 32760); 

    -- Get BLOB 
    SELECT SIMS_PROD.publish_rpt_new.RPT_CONTENTS INTO t_blob FROM  SIMS_PROD.publish_rpt_new; 

    -- Retrieving BLOB 
    WHILE t_position < t_totalsize 
     LOOP 
     dbms_lob.READ (t_blob, t_chucklen, t_position, t_chuck); 
     utl_file.Put_raw (t_output, t_chuck); 
     utl_file.Fflush (t_output); 
     t_position := t_position + t_chucklen; 
     t_remain := t_remain - t_chucklen; 

     IF t_remain < 4096 THEN t_chucklen := t_remain; 
     END IF; 
     END LOOP; 

    END LOOP; 
END; 
+0

'alter session set current_schema = sims_prod;' устранит указанную необходимость включения схемы в анонимный блок. –

ответ

0

Попробуйте заменить линию 13 с этим:

FOR X IN (SELECT RPT_FILE_NAME, RPT_CONTENTS FROM SIMS_PROD.PUBLISH_RPT) 
0

Это будет слишком поздно ответ, но по крайней мере вы будете знать, где вы сделали ошибку. Проблема заключается в том, если вы используете:

FOR X IN (SELECT a, b from table) LOOP

Вы должны использовать X.a в следующих утверждениях этого цикла, чтобы должным образом относится к значениям выбранных строк.

Так что в вашем коде вам нужно было изменить SIMS_PROD.publish_rpt_new.RPT_CONTENTS на X.SIMS_PROD.publish_rpt_new.RPT_CONTENTS.

Я еще не прочитал остальную часть вашего кода, поэтому, возможно, могут быть и другие ошибки.

Смежные вопросы