In "APEX Collections" hineinsehen - außerhalb der Anwendung
Nach einer Idee von Walter Meier, Siemens AG, München

APEX Collections sind sind bekanntlich das Mittel der Wahl, wenn es darum geht, mehrere Datensätze in einer Sitzung zwischenzuspeichern, man aber keine "richtige" Tabelle verwenden möchte. APEX Collections werden mit dem PL/SQL-Paket APEX_COLLECTION verwaltet - die darin gespeicherten Datensätze können aus der View APEX_COLLECTIONS ausgelesen werden.

Die Inhalte einer Collection sind an die APEX-Session, den Workspace und die Applikation gebunden. In einer anderen Session sind die Inhalte also schon nicht mehr sichtbar. Wenn eine Collection (bspw. "MEINE_COLLECTION") in einer APEX-Anwendung mit Inhalten gefüllt wurde, führt eine SQL*Plus-Abfrage auf die View APEX_COLLECTIONS stets zu einer leeren Ergebnismenge:

SQL> select * from apex_collections;

Es wurden keine Zeilen ausgewählt

Geht es ans Debugging einer APEX-Anwendung, so würde man sich schon wünschen, die Inhalte einer Collection aus SQL*Plus, dem SQL Developer oder einer anderen APEX-Sitzung heraus ansehen zu können. Um dies zu erreichen, schauen wir zunächst einfach mal in die Definition der View APEX_COLLECTIONS hinein. Die folgenden SQL-Kommandos müssen Sie als DBA absetzen ...

SQL> select owner, synonym_name, table_owner, table_name from dba_synonyms where synonym_name = 'APEX_COLLECTIONS';

OWNER           SYNONYM_NAME         TABLE_OWNER     TABLE_NAME
--------------- -------------------- --------------- --------------------
PUBLIC          APEX_COLLECTIONS     APEX_030200     APEX_COLLECTIONS
APEX_030200     APEX_COLLECTIONS     APEX_030200     WWV_FLOW_COLLECTIONS

Die View heißt also eigentlich WWV_FLOW_COLLECTIONS und liegt (wie alle APEX-Objekte) im Schema APEX_030200. Schauen Sie sich als nächstes die View-Definition an.

SQL> set long 20000
SQL> select text from dba_views where view_name = 'WWV_FLOW_COLLECTIONS';

TEXT
----------------------------------------------------------------------
select 
  c.collection_name, 
  m.seq_id, m.c001, m.c002, m.c003, m.c004, m.c005, m.c006, m.c007,
  m.c008, m.c009, m.c010, m.c011, m.c012, m.c013, m.c014, m.c015,
  m.c016, m.c017, m.c018, m.c019, m.c020, m.c021, m.c022, m.c023, 
  m.c024, m.c025, m.c026, m.c027, m.c028, m.c029, m.c030, m.c031, 
  m.c032, m.c033, m.c034, m.c035, m.c036, m.c037, m.c038, m.c039, 
  m.c040, m.c041, m.c042, m.c043, m.c044, m.c045, m.c046, m.c047,
  m.c048, m.c049, m.c050, m.clob001, m.md5_original
from wwv_flow_collections$ c, wwv_flow_collection_members$ m
where c.id = m.collection_id
   and c.session_id = (select v('SESSION') from dual)
   and c.security_group_id = (select wwv_flow.get_sgid from dual)
   and c.flow_id = (select nv('FLOW_ID') from dual)

Merken Sie schon, wie vorteilhaft und angenehm es ist, mit einem datenbankgestützten Werkzeug zu arbeiten ...?

Die WHERE-Klausel dieser View bewirkt also, dass man die Collection-Inhalte aus SQL*Plus heraus nicht betrachten kann. Man könnte nun also mit PL/SQL-Prozeduren die Workspace-ID (finden Sie über die View APEX_WORKSPACES heraus), die Applikations-ID und die Session-ID (kann aus der URL im Browser entnommen werden) setzen - anschließend kann man die Collection lesen ...

begin
  wwv_flow_api.set_security_group_id(1048427233631152);
  wwv_flow.g_flow_id := 102;
  wwv_flow.g_instance := 2447855502924756;
end;
/

select c001, c002 from apex_collections
where collection_name = 'MEINE_COLLECTION';

C001                C002 
------------------- ---------------------------
XXX                 YYY
XXXXXX1             ZZZZ
:                   :

Wem das zu mühsam ist, der kann sich auch (als DBA) eine neue View erzeugen, die eben ohne die WHERE-Klauseln arbeitet - geben Sie der View aber auf jeden Fall einen anderen Namen und schützen Sie sie vor unberechtigten Zugriffen: Vergeben Sie das SELECT-Privileg daran niemals an PUBLIC.

CREATE OR REPLACE VIEW SYS.MY_APEX_COLLECTIONS_DEBUG 
AS
SELECT 
  col.flow_id,
  col.user_id,
  col.session_id,
  col.collection_name,
  colm.seq_id,
  colm.c001, colm.c002, colm.c003,colm.c004, colm.c005, colm.c006,colm.c007, colm.c008, colm.c009, colm.c010,
  colm.c011, colm.c012, colm.c013,colm.c014, colm.c015, colm.c016,colm.c017, colm.c018, colm.c019, colm.c020,
  colm.c021, colm.c022, colm.c023,colm.c024, colm.c025, colm.c026,colm.c027, colm.c028, colm.c029, colm.c030,
  colm.c031, colm.c032, colm.c033,colm.c034, colm.c035, colm.c036,colm.c037, colm.c038, colm.c039, colm.c040,
  colm.c041, colm.c042, colm.c043,colm.c044, colm.c045, colm.c046,colm.c047, colm.c048, colm.c049,
  colm.clob001
FROM apex_030200.wwv_flow_collections$ col,
     apex_030200.wwv_flow_collection_members$ colm
WHERE col.id = colm.collection_id;

Nun können Sie die Collection-Inhalte mit einfachen SQL-Kommandos ansehen; das Debugging wird so wesentlich einfacher ...

Zurück zur Community-Seite