Skip to Main Content
Feature Request FR-2986
Product Area Developer Experience
Status CLOSED

4 Voters

Allow "instead of triggers" on views on apex_collections

manfred.gahr Public
· Feb 22 2023

The Idea

apex_collections are a nightmare to use for storing large amount of items. “Was last_name column C023 or C032?” Permuting column names in read / insert / update commands on collections are a nightmare to find.

I would like to create views with proper column names on apex_collections and allow insert / update / delete via instead-of-triggers, that call the corresponding apex_collection.add/update/delete_member functions.

The Problem

For some reason the execution of "instead of triggers" for views on APEX_collections is not allowed. REVION-hotline says that this is a general restriction of Oracle APEX environment they cannot alleviate :-(

You can create the trigger, yet get an "ORA-01031: insufficient privileges" error when trying to execute the trigger. I cannot see any security reasons for this restriction, since you can modify APEX_collections via PL/SQL-packages provided by the Oracle APEX team only.

The Big Advantage

Views on apex_collections with insert/update/delete triggers would allow to use apex_collections like ordinary tables. Hence one could use all standard wizards and functionality of APEX for forms, reports, interactive grids etc. That would solve a lot of problems in complex apps and make code so much saver and easier to read.

For testing
Please run attached script to create a view and two instead-of-triggers for insert and update in any Oracle APEX account. At the end of the script you find a PL/SQL-block which tries to insert a record. The "instead of insert"-trigger does not reach the first statement dbms_output.put_line('Trying insert to ' || :new.collection_name); So it is a security restriction to execute the trigger.

create or replace view dm_vw_person_import as
select
    collection_name,
    seq_id as id,
    C001 as title,
    C002 as first_name,
    C003 as last_name
from APEX_collections;
/

create or replace trigger dm_vw_person_import_insert_trg
instead of insert on dm_vw_person_import
for each row
begin
    dbms_output.put_line('Trying insert to ' || :new.collection_name);
    apex_collection.add_member (
        p_collection_name => :new.collection_name,
        p_c001 => :new.title,
        p_c002 => :new.first_name,
        p_c003 => :new.last_name
    );
            
end dm_vw_person_import_insert_trg;
/

create or replace trigger dm_vw_person_import_update_trg
instead of update on dm_vw_person_import
for each row
begin
    apex_collection.update_member (
        p_collection_name => :new.collection_name,
        p_seq => :new.id,
        p_c001 => :new.title,
        p_c002 => :new.first_name,
        p_c003 => :new.last_name
    );
            
end dm_vw_person_import_update_trg;
/

-- Try to insert a record
declare
    v_rec dm_vw_person_import%rowtype;
begin
    -- create collection
    apex_collection.create_or_truncate_collection(
        p_collection_name => 'adr_collection'
    );


    v_rec.collection_name := 'adr_collection';
    v_rec.first_name := 'Hans';
    v_rec.last_name := 'Müller';

    insert into dm_vw_person_import values v_rec;
end;
/


We reviewed this idea carefully, and while it was interesting, we concluded that due to all the internal implications we need to take into account, it is not feasible in APEX.

Comments

Comments

  • ino.laurensse OP 2.5 years ago
    from APEX_collections;
    

    You are forgetting

    where collection_name = ‘your collection’
    
  • mike_kutz OP 2.5 years ago

    IIRC - this is a DB issue, not an APEX issue.  I forgot how far I got in my attempts going that route.

    In the end, I created an API (package) for the VIEW on the Collection. The API included an Automatic DML replacement and a Procedure for IG per-row DML.  Its based on a code template. so, i just have to tell the code generator the name of the table i want it to look like and the resulting object names.

     (code review, do one trigger and use UPDATING, INSERTING, and DELETING in IF/CASE block.)

  • vincent morneau Admin OP 2.5 years ago

    Hi, we're keeping this in mind if/when APEX revisits the collection architecture. Right now it is unfortunately infeasible.

  • dirk_strack OP 1.8 years ago

    Well, there is an workaround on this problem with error "ORA-20987: APEX - ORA-01031: insufficient privileges": 

    https://strack-software-development.blogspot.com/2019/02/dml-support-for-apexcollections.html

  • manfred.gahr OP 1.8 years ago

    @dirk_strack Hi Dirk, cool idea! But quite “durch die Brust ins Auge” (through the chest into the eye) to solve such a simple problem. Thanks for your comment, Manfred

  • manfred.gahr OP 1.8 years ago

    @vincent morneau Hi Vincent, your post is a while ago but franquly I do not understand, why this should be “unfeasible". Simply dropping the restriction which would allow to create a view on apex_collections and instead of triggers for IUD where you call the appropriate apex_collection API functions. I cannot see any security risks or other hassles. Benefits: use collections on IG and forms as normal tables → would allow for easy editing collections before committing data without these complex workarounds proposed by Mike and Dirk.

  • mike_kutz OP 1.8 years ago

    @manfred.gahr 

    My current solution is to use Real Application Security (RAS) and apply an RLS policy (based on session ID) to an actual table ( no C001, D002 columns) that auto-removes the data on log-out.

    It's still a lot of work (not as much as my API).  and IMO - this should be an RDBMS/APEX feature. (IIRC - I suggested this, but it was closed as “not enough interest”)

  • fac586 OP 12 months ago

    @manfred.gahr  I do not understand, why this should be “unfeasible". Simply dropping the restriction which would allow to create a view on apex_collections and instead of triggers for IUD where you call the appropriate apex_collection API functions. I cannot see any security risks or other hassles.

    It is infeasible because the primary problem exists at database level.

    Oracle raises the ORA-01031 exception after parsing an insert/update/delete statement on APEX_COLLECTIONS because the application parsing schema executing the DML does not have the required privileges on the objects underlying the view. This occurs before the INSTEAD OF trigger is invoked.

    Any attempt by the APEX team to work around that would open up security issues and inconsistencies on the APEX side.