Skip to Main Content
  • Questions
  • Fire a trigger on a nested-table column

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Alessio.

Asked: August 30, 2021 - 7:02 am UTC

Last updated: August 31, 2021 - 1:08 pm UTC

Version: 11.2.0.3.0

Viewed 1000+ times

You Asked

Hi Tom,
I have a question about trigger on nested table:
I'd like to know if there is any way to fire a trigger on a nested_table column when the procedure that insert/modify data uses unnesting queries like these:

INSERT INTO TABLE(SELECT nested_table FROM parent_table WHERE id = 1) VALUES
UPDATE TABLE(SELECT nested_table FROM parent_table WHERE id = 1) SET...
DELETE FROM TABLE(SELECT nested_table FROM parent_table WHERE id = 1);


It's a legacy software and I cannot modify the procedure that insert/modify records so I want to use a trigger before insert.

Unfortunately I just find that triggers on parent_table don't work in that case because the procedure initializes the nested_table column with an empty collection and then insert a record using the cast operator TABLE.

So when the trigger fires the collection is empty and I obtain ORA-06502

Also trying to reference directly the nested_table using the name defined in the STORE clause fails with ORA-22812

I updated a livesql link to better explain the case.

Thanks in advance

with LiveSQL Test Case:

and Chris said...

To stop getting ORA-06502 when trying to iterate over an empty nested table, first check it has elements!

This gives a trigger body along the lines of:

begin 
  if :new.empfiles.count > 0 then
    for i in :new.empfiles.first..:new.empfiles.last 
    loop 
        if :new.empfiles(i).filename like '%\_pdf.p7m' escape '\' then 
            :new.empfiles(i).filename:=replace(:new.empfiles(i).filename,'_pdf.p7m','.pdf.p7m'); 
        end if; 
    end loop; 
  end if;
end; 


But this only solves part of the issue. When you have:

insert into table ( select nested_table...


You're not really inserting to the parent table, but the nested table. The triggers don't fire for this.

It's a legacy software and I cannot modify the procedure that insert/modify records so I want to use a trigger before insert.

Why not? If you're able to add triggers to the table, surely you can change the procedure too?

Ideally you'd change the procedure to initialize the nested table first, then insert it, e.g.:

create or replace procedure addfile (
  l_id number, l_empname varchar2, l_empsurname varchar2, l_myfilename varchar2
) 
is 
  l_myfiles myfile; 
begin 
  l_myfiles := myfile ( myfilet( sysdate, l_myfilename ) );
  insert into myreg values ( l_id, l_empname, l_empsurname, l_myfiles ); 
end; 


Though if you do this it's better to remove the trigger altogether and place the file renaming logic in the procedure.

If you're not allowed to change the procedure because reasons, your options are limited.

It's possible you could rename the table and create a view over it with the table's original name. Then create instead of triggers on the view to do this.

The other option is to create a post-insert update routine, that you call to change the nested table data.

Is this answer out of date? If it is, please let us know via a Comment

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library