APEX: BLOB loading from temporary table

I am trying to create a simple viewer application using Oracle APEX 4.1.1. The information that will be displayed is in a table in another database, and then in the database containing the schema that the APEX application accesses. This remote table is accessed using View (RemoteTableView) and a database link. The view works as expected, including the inapplicability of Oracle to select a LOB column element through a database link.

In the APEX application, I defined a procedure (DownloadFiles) that runs whenever a BLOB from a view needs to be loaded as instructed in Oracle Application Express Advanced Tutorials

This works great when the APEX application is built on an existing table containing BLOB elements without any problems.

However, in RemoteTableView the process is slightly different. Additional lines of code are added to the DownloadFiles procedure, which must be loaded with every call to an element in the view. Insert the actual BLOB from the RemoteTableView into the temporary table (TempTable). Then DownloadFile is called on TempTable to download the BLOB. (All this is done to bypass the direct selection of LOB objects via DB-Link). No COMMIT.

Unfortunately, APEX applications fail when an item is called for download using "This web page was not found. Web page not found for web address: ... / f? P = 101: 7: 1342995827199601 :: NO: : P7_DOC_ID :. 3001 "

. ( PL/SQL Developer), BLOB .

, : APEX . , ? , LOB.

BLOB. ( ). PL/SQL " ": P2_BLOB_ID BLOB.

DECLARE
  v_mime      VARCHAR2(48);
  v_length    NUMBER(38);
  v_file_name VARCHAR2(38);
  Lob_loc     BLOB;
BEGIN
  DELETE FROM [TemporaryTable];
  --
  INSERT INTO [TemporaryTable]( [attr1]
                              , [attr2]
                              , [blob]
                              , [mime] )
  SELECT [attr1]
  ,      [attr2]
  ,      [blob]
  ,      [mime]
  FROM   [RemoteTableView]
  WHERE  [attr1] = :P2_BLOB_ID
  AND    ROWNUM  = 1;
  --
  SELECT [mime]
  ,      [blob]
  ,      [attr1]
  ,      DBMS_LOB.GETLENGTH( [blob] )
  INTO   v_mime
  ,      lob_loc
  ,      v_file_name
  ,      v_length
  FROM   [TemporaryTable]
  WHERE  [attr1] = :P2_BLOB_ID;
  --
  owa_util.mime_header( nvl(v_mime,'application/octet'), FALSE );
  htp.p('Content-length: ' || v_length);
  htp.p('Content-Disposition:  attachment; filename="'||replace(replace(substr(v_file_name,instr(v_file_name,'/')+1),chr(10),null),chr(13),null)|| '"');
  owa_util.http_header_close;
  wpg_docload.download_file( Lob_loc );
END;
+4
3

apex_application.stop_apex_engine wpg_docload. HTTP, , .

  owa_util.mime_header( nvl(v_mime,'application/octet'), FALSE );
  htp.p('Content-length: ' || v_length);
  htp.p('Content-Disposition:  attachment; filename="'||replace(replace(substr(v_file_name,instr(v_file_name,'/')+1),chr(10),null),chr(13),null)|| '"');
  owa_util.http_header_close;
  wpg_docload.download_file( Lob_loc );
  apex_application.stop_apex_engine;

, :

?

. . , apex . Apex . apex 1 , , , , . " " , :

HTTP, , HTML-, . - , . , , , . , , . Express .

2.4.1 ?

- , ( ) . . Application Express ( ) ( ) .

, . .

Oracle , . Oracle Application Express , , . , Express Oracle . .

, , . , GTT - onload ajax-. , .
Apex apex_collection, apex.

+3

CLOB BLOB Oracle PL/SQL

Oracle 11gR2. APEX , . - DB, APEX, , Oracle DBLinks.

INTRO: OP , , , " " " ", , OP Oracle.

- LOB dblink. , : ORA-22992: cannot use LOB locators selected from remote tables.

, , . , 2010 , - , . , .

: , , ( ) / , "remote" "local" ... , , , .

REMOTE SERVER

REMOTE DATABASE INSTANCE.

 CREATE TYPE object_row_type AS OBJECT (
    MY_ORDER   NUMBER,
    MY_ID      NUMBER,
    MY_CLOB_AS_VARCHAR   VARCHAR2(4000));

 CREATE TYPE object_table_type AS TABLE OF object_row_type;

DDL

 CREATE TABLE REMOTE_CLOB_TABLE (
    ID       NUMBER      NOT NULL,
    MY_CLOB  CLOB
 );


 INSERT INTO REMOTE_CLOB_TABLE(id, my_clob) 
    VALUES(1001, 'When can the expenditure enter behind a shock recovery? The strategy fishes underneath the sugar. An after wrap masters a slim moron. The twenty dish hunts an aunt opposite the credible zone. The phoenix copes. The diagonal flours a bag against the positive fan.');

 INSERT INTO REMOTE_CLOB_TABLE(id, my_clob) 
    VALUES(2001, 'A traveled concept hides a removed skin. A liquid steers whatever understandable heart. A curve strips away an assembly. A wartime freezes the outcome.');

 INSERT INTO REMOTE_CLOB_TABLE(id, my_clob) 
    VALUES(3001, 'A lonely genre bolts beside the obliging prisoner. The freedom stamps! Its game fluid dictates. How will her power imagine the quantum?');

 INSERT INTO REMOTE_CLOB_TABLE(id, my_clob) 
    VALUES(4001, 'The young office caps the travelled temper. A forum husbands the family. The detail peers. Her jammed agenda experiments against the regarding obstruction.');

 INSERT INTO REMOTE_CLOB_TABLE(id, my_clob) 
    VALUES(5001, 'The incredible drivel suspects. A vehicle reads. A cardboard jacket shares the insult above the baking constitutional. Outside this effort composes the invited jest.');

 INSERT INTO REMOTE_CLOB_TABLE(id, my_clob) 
    VALUES(6001, 'The vegetarian strength marches underneath an opposing intellectual. The ringed lifestyle bends the archaic thirst. A saga escapes with the ego. The acorn escapes against the old lark.');

 INSERT INTO REMOTE_CLOB_TABLE(id, my_clob) 
    VALUES(7001, 'Whatever bear furthers a mania. The norm contours a ruin. How can the reasoned composite cough? With a unimportant timetable reasons the sorry frog. Can the key jacket toss an author?');

 COMMIT;

Script

 CREATE or REPLACE FUNCTION CONVERT_CLOB_TO_VARCHAR RETURN object_table_type PIPELINED
    IS 

 PRAGMA AUTONOMOUS_TRANSACTION;

    v_clob_length   number;
    v_loops         number;
    v_varchar_size  number := 100; 
    -- purposely set to a small value to see the looping step work
    -- normally set to max varchar2 size (4000 BYTE).

 BEGIN

 FOR cur IN (SELECT id, my_clob from remote_clob_table)  
 LOOP

       v_clob_length := dbms_lob.getlength (cur.my_clob);
       v_loops := trunc(v_clob_length/v_varchar_size) + 
          sign (mod(v_clob_length, v_varchar_size )) - 1;


    FOR i IN 0..v_loops
    LOOP

       -- This chunks the CLOB/LOB file from beginning to end in chunks
       --   of pre-designated size.

       PIPE ROW(object_row_type(i+1, cur.id, dbms_lob.substr(cur.my_clob,
          v_varchar_size, v_varchar_size * i + 1 )));

    END LOOP;


 END LOOP;

 COMMIT;
 RETURN;

 END;

VIEW CLOB:

 CREATE or REPLACE VIEW myremotedata AS
    SELECT * FROM TABLE(CONVERT_CLOB_TO_VARCHAR) a;

LOCAL DATABASE INSTANCE.

DB :

 CREATE PUBLIC DATABASE LINK MY_REMOTE_CONNECTION
    CONNECT TO REMOTE_USER
    IDENTIFIED BY <PWD>
    USING <TNS or DIRECT CONNECTION STRING>

:

 CREATE OR REPLACE TYPE MY_TABLE_TYPE AS TABLE OF VARCHAR2(4000);

PL/SQL VARCHAR Pieces CLOB

 CREATE OR REPLACE FUNCTION F_VARCHAR_TO_CLOB (input_table_of_varchar  my_table_type)
    RETURN CLOB IS
    PRAGMA AUTONOMOUS_TRANSACTION;

    v_clob   clob;

 BEGIN
    FOR i in 1..input_table_of_varchar.COUNT
    LOOP

    v_clob := v_clob || input_table_of_varchar(i);

    END LOOP;

 RETURN v_clob;

 END;

 CREATE OR REPLACE VIEW MY_REMOTE_DATA AS

    SELECT a.id,
      f_varchar_to_clob( 
         CAST( MULTISET( SELECT b.MY_CLOB_AS_VARCHAR
                           FROM remote_user.myremotedata@my_remote_connection b
                          WHERE a.id = b.my_id
                          ORDER BY b.my_id ASC, b.my_order ASC ) 
                                     as my_table_type)

                     ) MY_CLOB

 FROM REMOTE_CLOB_TABLE@my_remote_connection a;

, , . , CLOB . . , 4 000 varchar2, CLOB, .

: MYREMOTEDATA

Remote DB Link Query for Converted CLOB Data

CONVERT_CLOB_TO_VARCHAR PL/SQL.

: ( CLOB)

select id, my_clob from my_remote_data where id between 1000 and 5000

ID MY_CLOB

1001 When can the expenditure enter behind a shock recovery? The strategy fishes unde rneath the sugar. An after wrap masters a slim moron. The twenty dish hunts an a unt opposite the credible zone. The phoenix copes. The diagonal flours a bag aga inst the positive fan.
2001
A traveled concept hides a removed skin. A liquid steers whatever understandable heart. A curve strips away an assembly. A wartime freezes the outcome.
3001
A lonely genre bolts beside the obliging prisoner. The freedom stamps! Its game fluid dictates. How will her power imagine the quantum?
4001
The young office caps the travelled temper. A forum husbands the family. The det ail peers. Her jammed agenda experiments against the regarding obstruction.

4 rows selected.

VARCHAR , CLOB-.

:

, , Oracle RDBMS , , CLOBs BLOB- .

, , , (.. ).

+1

APEX_COLLECTIONS .

DECLARE
  v_mime      VARCHAR2(48);
  v_length    NUMBER(38);
  v_file_name VARCHAR2(38);
  Lob_loc     BLOB;
BEGIN
  DELETE FROM [TemporaryTable];
  --
  INSERT INTO [TemporaryTable]( [attr1]
                              , [attr2]
                              , [blob]
                              , [mime] )
  SELECT [attr1]
  ,      [attr2]
  ,      [blob]
  ,      [mime]
  FROM   [RemoteTableView]
  WHERE  [attr1] = :P2_BLOB_ID
  AND    ROWNUM  = 1;
  --
  SELECT [mime]
  ,      [blob]
  ,      [attr1]
  ,      DBMS_LOB.GETLENGTH( [blob] )
  INTO   v_mime
  ,      lob_loc
  ,      v_file_name
  ,      v_length
  FROM   [TemporaryTable]
  WHERE  [attr1] = :P2_BLOB_ID;
  --
  APEX_COLLECTION.CREATE_OR_TRUNCATE_COLLECTION('COLLECTION1');
  --
  apex_collection.add_member( p_collection_name => 'COLLECTION1'
                            , p_c001 => v_mime
                            , p_c002 => v_file_name
                            , p_n001 => v_length
                            , p_blob001 => lob_loc
                            );
  --
  DELETE FROM [TemporaryTable];
  --
  SELECT c001, blob001, c002, n001
  INTO   v_mime,lob_loc,v_file_name,v_length
  FROM   apex_collections
  WHERE  collection_name = 'COLLECTION1'
  AND    c002            = :P2_BLOB_ID;
  --
  owa_util.mime_header( nvl(v_mime,'application/octet'), FALSE );
  htp.p('Content-length: ' || v_length);
  htp.p('Content-Disposition:  attachment; filename="'||replace(replace(substr(v_file_name,instr(v_file_name,'/')+1),chr(10),null),chr(13),null)|| '"');
  owa_util.http_header_close;
  wpg_docload.download_file( Lob_loc );
END;

The BLOB is still called from the temporary table after it is inserted from the remote table. But then it is saved from the temporary table in APEX_COLLECTIONS, from where it is finally retrieved after it is called for loading.

+1
source

Source: https://habr.com/ru/post/1535580/


All Articles