Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle APEX Новый топик    Ответить
 Снова apex_util.get_blob  [new]
Gustly
Member

Откуда:
Сообщений: 1409
Добрый день.

Задача - в репорте сделать ссылку на открытие файла в новом окне.

Проблема - репорт этот не основной, то есть фетчится изначально не в него, поэтому примеры стандартные не катят, где один репорт один фетч.

С досады сделал JS кодом
$('td[headers=OPEN] a').attr('target','_blank');
То есть в поле типа БЛОБ подредактировал ссылку, которую апекс генерит.

Есть ли нормальный способ получения ссылок на файлы, без создания каких-то фетчей и айтемов? Хочу PL/SQL код, который мне выплюнет готовую ссылку
<a href="apex_util.get_blob?s=1338583178092&amp;a=106&amp;c=6954302679808170&amp;p=20&amp;k1=244&amp;k2=10&amp;ck=CEB51B4DD3BE81197134A8BEA096039D&amp;rt=CR">TEXT</a>
3 апр 14, 12:27    [15826427]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
Gustly,

Есть много способов делать ссылки,

опишите подробнее, какой используете сейчас:

- Отчет стандартный или интерактивный ?

- Какое средство сейчас используете для генерации ссылки ?
7 апр 14, 12:06    [15842436]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
Gustly
Member

Откуда:
Сообщений: 1409
SvDev,

Оба вариантов отчета.

Сейчас в маске поля указывается BLOB со всеми параметрами (таблица, поле с ИД, поле с блобом) и апекс сам в итоге генерит ссылку.
7 апр 14, 12:38    [15842703]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
Gustly,

Как вариант, смотрите id в wwv_flow_files

потом генерируете ссылку, вида <a href="p?n=id">ссылка</a>
7 апр 14, 14:34    [15843731]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
Gustly
Member

Откуда:
Сообщений: 1409
SvDev,

Можно по подробнее. У меня файлы хранятся не в wwv_flow_files.
7 апр 14, 14:48    [15843855]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
Gustly,

Тьфу ты, невнимательно прочитал.

Тогда

- Создается глобальная переменная, где будет ид из таблицы ( G_DOCUMENT_ID - app item, тип unresctricted )

- Делается application process, например DOWNLOAD_SERVICE, типа onDemand

declare
    p_file_name varchar2(32767);
    p_file_blob blob;
    p_file_mime varchar2(255);
begin
    select ...
      into p_file_name, p_file_blob, p_file_mime
    from ваша таблица
    where id = :G_DOCUMENT_ID;

    htp.init;
    owa_util.mime_header( p_file_mime, false );
    htp.p ('content-length: ' || DBMS_LOB.getlength( lob_loc => p_file_blob ) );

    if INSTR(UPPER(OWA_UTIL.GET_CGI_ENV('HTTP_USER_AGENT')), 'MSIE') > 0 then

      htp.p ('Content-Disposition:  attachment; filename="' 
           || UTL_URL.ESCAPE( p_file_name, FALSE, 'UTF-8' ) || '"');
    else
      htp.p ('Content-Disposition:  attachment; filename="' 
           || p_file_name || '"');
    end if;
    owa_util.http_header_close;

    wpg_docload.download_file( p_file_blob );
end;


- в очтете генерируете ссылку вида:

<a href="f?p=&APP_ID.:&APP_PAGE.:&APP_SESSION.:APPLICATION_PROCESS=DOWNLOAD_SERVICE::G_DOCUMENT_ID:ИД">ссылка</a>


Готово
7 апр 14, 16:02    [15844582]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
Gustly
Member

Откуда:
Сообщений: 1409
SvDev,

Изврат конечно, но спасибо за способ.
7 апр 14, 16:08    [15844641]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
аутентификацию можно как-нибудь так проверить:

declare
    p_file_name varchar2(32767);
    p_file_blob blob;
    p_file_mime varchar2(255);
begin
  if APEX_AUTHENTICATION.IS_AUTHENTICATED then

    select ...
      into p_file_name, p_file_blob, p_file_mime
    from ваша таблица
    where id = :G_DOCUMENT_ID;

    htp.init;
    owa_util.mime_header( p_file_mime, false );
    htp.p ('content-length: ' || DBMS_LOB.getlength( lob_loc => p_file_blob ) );

    if INSTR(UPPER(OWA_UTIL.GET_CGI_ENV('HTTP_USER_AGENT')), 'MSIE') > 0 then

      htp.p ('Content-Disposition:  attachment; filename="' 
           || UTL_URL.ESCAPE( p_file_name, FALSE, 'UTF-8' ) || '"');
    else
      htp.p ('Content-Disposition:  attachment; filename="' 
           || p_file_name || '"');
    end if;
    owa_util.http_header_close;

    wpg_docload.download_file( p_file_blob );
  else
    htp.init;
    owa_util.mime_header( 'text/html', true );
    htp.p('Пожалуйста, залогиньтесь');
  end if;
end;


Gustly
Изврат конечно, но спасибо за способ.

Перепробовав кучу способов, этот кажется мне самым нормальным из всех нормальных :)

Один раз написать, зато никаких ограничений на реализацию.
7 апр 14, 16:16    [15844719]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
Gustly
Member

Откуда:
Сообщений: 1409
SvDev,

Я бы хотел разврапить и выпотрошить оригинал, который JS функицю генерит.
7 апр 14, 16:20    [15844757]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
Gustly,

Этот самый apex_util.get_blob сделан внутри аналогично, но только со всякими багами, поэтому многие юзают wpg_docload напрямую - это нормальный распространенный способ.
7 апр 14, 16:27    [15844829]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
Gustly
Member

Откуда:
Сообщений: 1409
SvDev,

Мне непонятно, что за параметры оно передает, какие-то длинные ИДшники.
7 апр 14, 16:38    [15844937]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
Gustly,

Например, с функцией apex_util.get_blob_file_src, там аналогичная ситуация (по количеству параметров), и устанавливать их напрямую - то еще удовольствие, можете почитать:

https://community.oracle.com/message/3861537#3861537

Да и параметры вполне могут поменяться от версии к версии...
7 апр 14, 16:49    [15845016]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
Менее продвинутый вариант:

Downloading Documents from the Custom Table
7 апр 14, 17:24    [15845202]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Снова apex_util.get_blob  [new]
iv_roman_vl
Member

Откуда:
Сообщений: 56
SvDev
Gustly,

Тьфу ты, невнимательно прочитал.

Тогда

- Создается глобальная переменная, где будет ид из таблицы ( G_DOCUMENT_ID - app item, тип unresctricted )

- Делается application process, например DOWNLOAD_SERVICE, типа onDemand

declare
    p_file_name varchar2(32767);
    p_file_blob blob;
    p_file_mime varchar2(255);
begin
    select ...
      into p_file_name, p_file_blob, p_file_mime
    from ваша таблица
    where id = :G_DOCUMENT_ID;

    htp.init;
    owa_util.mime_header( p_file_mime, false );
    htp.p ('content-length: ' || DBMS_LOB.getlength( lob_loc => p_file_blob ) );

    if INSTR(UPPER(OWA_UTIL.GET_CGI_ENV('HTTP_USER_AGENT')), 'MSIE') > 0 then

      htp.p ('Content-Disposition:  attachment; filename="' 
           || UTL_URL.ESCAPE( p_file_name, FALSE, 'UTF-8' ) || '"');
    else
      htp.p ('Content-Disposition:  attachment; filename="' 
           || p_file_name || '"');
    end if;
    owa_util.http_header_close;

    wpg_docload.download_file( p_file_blob );
end;


- в очтете генерируете ссылку вида:

<a href="f?p=&APP_ID.:&APP_PAGE.:&APP_SESSION.:APPLICATION_PROCESS=DOWNLOAD_SERVICE::G_DOCUMENT_ID:ИД">ссылка</a>


Готово


почемуто ссылка сабмитит на эту же страницу.файл не загружается и ошибок нет(
В чем может быть причина?
3 авг 17, 22:05    [20699186]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
iv_roman_vl,

См. авторизацию на странице и внутри процесса + apex debug.
4 авг 17, 00:43    [20699366]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
iv_roman_vl
Member

Откуда:
Сообщений: 56
SvDev
iv_roman_vl,

См. авторизацию на странице и внутри процесса + apex debug.



пробую этот код прогнать прям в базе.
ругается на owa_util.mime_header

06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause: An arithmetic, numeric, string, conversion, or constraint error
occurred. For example, this error occurs if an attempt is made to
assign the value NULL to a variable declared NOT NULL, or if an
attempt is made to assign an integer larger than 99 to a variable
declared NUMBER(2).
*Action: Change the data, how it is manipulated, or how it is declared so
that values do not violate constraints.




пробовал и так и так:
owa_util.mime_header( nvl(p_file_mime,'application/octet'), false );
owa_util.mime_header( nvl(p_file_mime,'text/plain'), false );

там у меня текстовый документ .txt
4 авг 17, 10:32    [20699835]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
iv_roman_vl
Member

Откуда:
Сообщений: 56
Даже и на это ругается.

begin
htp.init;
owa_util.mime_header();
end;

Хотя посмотрел функцию desc sys.owa_util, параметры есть по умолчанию

MIME_HEADER CCONTENT_TYPE VARCHAR2 IN DEFAULT
BCLOSE_HEADER PL/SQL BOOLEAN IN DEFAULT
CCHARSET VARCHAR2 IN DEFAULT
4 авг 17, 10:37    [20699859]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
iv_roman_vl,

Не инициализирована CGI среда скорее всего.
Например, выполняйте в SQL Worshop > SQL Commands.
4 авг 17, 11:47    [20700222]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
irbis_al
Member

Откуда: Симферополь
Сообщений: 1330
iv_roman_vl,

Вот моя тема
http://www.sql.ru/forum/1146167/upload-download-file?hl=blob
Там я окончательный пример вывел...
Вот пример сервиса картинки(рабочий)
declare

l_rcursor sys_refcursor;
pget varchar2(32767);
mimetype varchar2(80);
p_file_name varchar2(40);
t_blob blob;
t_clob clob;
l_rcursortile sys_refcursor;
pgettitle varchar2(32767);

 l_dest_offset   integer := 1;
   l_source_offset integer := 1;
   l_lang_context  integer := DBMS_LOB.DEFAULT_LANG_CTX;
   l_warning       integer := DBMS_LOB.WARN_INCONVERTIBLE_CHAR;

begin
select goodsblob into t_blob from #OWNER#.GOODSPICTURE where goods_id=:P6_GOODS_ID;

htp.flush;
owa_util.mime_header( mimetype, false );
 htp.print( 'Content-Length: ' || dbms_lob.getlength( t_blob ) );
  htp.p( 'Content-disposition: attachment; filename='||:P6_GOODS_ID||'.png;' );
owa_util.http_header_close; 
 wpg_docload.download_file( t_blob );
 --owa_util.http_header_close;
--htp.p(t_blob);
 --   dbms_lob.freetemporary(t_blob);
  --   dbms_lob.freetemporary(t_clob);
end;


Но Важен один момент...
URL идёт на другую страницу...а в ней процесс обязательно beforeheader расположен.
а в ней тот процесс

К сообщению приложен файл. Размер - 94Kb
4 авг 17, 14:50    [20701011]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
irbis_al,

Другая страница не обязательна, можно сделать условие на :request на текущей;
+ apex_application.stop_apex_engine нужно в случае before header поставить в конец, иначе боком может вылезти (из-за того что продолжается процесс отрисовки, например, при смене версии или веб сервера)

Я не люблю before header с тех пор как в 4.1 потребовали писать htp.init (в release notes) и пришлось переписывать код. ondemand удобен тем, что хорошо подходит для размещения глобальной логики.

У ТС, я полагаю, какая-то другая pl/sql ошибка, либо делает что-то другое, нужно apex debug смотреть и проверять ссылку, чтобы была именно такой, как указана.
4 авг 17, 18:05    [20701797]     Ответить | Цитировать Сообщить модератору
 Re: Снова apex_util.get_blob  [new]
SvDev
Member

Откуда: Челябинск
Сообщений: 1950
В 5.1 onDemand так же называется Ajax Callback.
4 авг 17, 18:15    [20701826]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle APEX Ответить