Use Global Temp Table to overcome Mutating Trigger issue

Hello all. I need to delete a line in a table, and thought I would get around the mutating trigger issue by creating a GTB table. I created 2 different triggers. One is a Row level trigger, the other a Statement level trigger.
The first trigger gathers the information I need to identify the line I want to delete. This is:
CREATE OR REPLACE TRIGGER Requisition_Capture
AFTER UPDATE OF Delivery_Code on Supply_Items
FOR EACH ROW
BEGIN
  IF :NEW.Delivery_Code = '#' THEN
    INSERT INTO Requisition_Storage
      (Req_Code)
    VALUES
      (:NEW.Requisition_Code);
  END IF;
END;And the second trigger deletes the line:
CREATE OR REPLACE TRIGGER SUPPLY_ITEM_RESET
AFTER INSERT ON Requisition_Storage
DECLARE
BEGIN
  DELETE FROM Supply_Items r
   WHERE r.Requisition_Code =
         (SELECT t.Req_Code
            FROM Requisition_Storage t, Supply_Items s
           WHERE t.Req_Code = s.Requisition_Code)
     AND r.Order_Qty = 0;
END;The GTB is as follows stores the information I need to delete the line.:
-- Create table
create global temporary table REQUISITION_STORAGE
  req_code VARCHAR2(20)
on commit delete rows;When the column Delivery_Code is updated in the Supply_Item table, and the value is reset to '#', I want to capture the Requisition_Code in the GTB, so I can run the statement level trigger and delete the reset row. However, I still have a mutating error problem. What am I missing?

The statement level trigger would need to be an AFTER UPDATE OF Supply_Items for this to work around the mutating trigger issue. You need to ensure that your UPDATE has finished updating all the rows that it is going to update before your statement-level trigger runs.
As has been pointed out, however, the desire to work around a mutating trigger error almost always indicates that you have a data model problem. And you're almost always better served by fixing the data model than working around the error.
Justin

Similar Messages

  • Use global temp table for DML error logging

    our database is 11.2.0.4 enterprise edition on solaris 10
    we are wondering if anyone has an opinion of or has done this before, to use a global temp table for DML error logging. We have a fairly busy transactional database with 2 hot tables for inserts. The regular error table created with dbms_errlog has caused many deadlocks which we don't quite understand yet. we have thought using global temp table for the purpose, and that seemed to work, but we can't read error from the GTT, the table is empty even reading from the same session as inserts. Does anyone have an idea why?
    Thanks

    The insert into the error logging table is done with a recursive transaction therefore it's private from your session which is doing the actual insert.
    Adapted from http://oracle-base.com/articles/10g/dml-error-logging-10gr2.php
    INSERT INTO dest
    SELECT *
    FROM  source
    LOG ERRORS INTO err$_dest ('INSERT') REJECT LIMIT UNLIMITED;
    99,998 rows inserted.
    select count(*) from dest;
      COUNT(*)
        99998
    SELECT *
    FROM  err$_dest
    WHERE  ora_err_tag$ = 'INSERT';
    1400    "ORA-01400: cannot insert NULL into ("E668983_DBA"."DEST"."CODE")"        I    INSERT    1000        Description for 1000
    1400    "ORA-01400: cannot insert NULL into ("E668983_DBA"."DEST"."CODE")"        I    INSERT    10000        Description for 10000
    1400    "ORA-01400: cannot insert NULL into ("E668983_DBA"."DEST"."CODE")"        I    INSERT    1000        Description for 1000
    1400    "ORA-01400: cannot insert NULL into ("E668983_DBA"."DEST"."CODE")"        I    INSERT    10000        Description for 10000
    rollback;
    select count(*) from dest;
      COUNT(*)
            0
    SELECT *
    FROM  err$_dest
    WHERE  ora_err_tag$ = 'INSERT';
    1400    "ORA-01400: cannot insert NULL into ("E668983_DBA"."DEST"."CODE")"        I    INSERT    1000        Description for 1000
    1400    "ORA-01400: cannot insert NULL into ("E668983_DBA"."DEST"."CODE")"        I    INSERT    10000        Description for 10000
    1400    "ORA-01400: cannot insert NULL into ("E668983_DBA"."DEST"."CODE")"        I    INSERT    1000        Description for 1000
    1400    "ORA-01400: cannot insert NULL into ("E668983_DBA"."DEST"."CODE")"        I    INSERT    10000        Description for 10000

  • Global Temp Table Not found - SSIS

    I am facing below error while using global temp table in SSIS.
    [OLE DB Destination [78]] Error: SSIS Error Code DTS_E_OLEDBERROR.  An OLE DB error has occurred. Error code: 0x80040E37.
    An OLE DB record is available.  Source: "Microsoft SQL Server Native Client 10.0"  Hresult: 0x80040E37  Description: "Table/view either does not exist or contains errors.".
    [OLE DB Destination [78]] Error: Failed to open a fastload rowset for " ##AGENTDTLS". Check that the object exists in the database.
    [SSIS.Pipeline] Error: component "OLE DB Destination" (78) failed the pre-execute phase and returned error code 0xC0202040.
    1) For data connection manager - Retain same connection is set to True
    2) Data Flow task - Delay Validation is set to True
    3) Destination Task - Using Temp Table - ValidateExternalMetadata is set to false.
    4) I am just using one data connection.
    5) before using the temp file I am checking if its exits and if yes drp it first and create it.
    Not able to understand the reason for failure.

    Why don't you use permanent table in tempdb?
    Kalman Toth Database & OLAP Architect
    SQL Server 2014 Design & Programming
    New Book / Kindle: Exam 70-461 Bootcamp: Querying Microsoft SQL Server 2012

  • Update Global Temp Table in Oracle 11g

    Hi Experts,
    Scenario: I have stored  procedure A which calls procedure B. Procedure B uses Global temp Tables(With On Commit Preserve Rows)  to work with the data.
    I am trying to update one of the GTT in Proc B but unable to do it .. via SQL or via PL/SQL Cursor/Collection. There is no syntax nor logical error and the PL/SQL proc completes execution successfully but the rows are not getting updated. My Db version is Oralce 11g 11203.
    Update statement is something like this.
    Update <GTT>
    SET amount1 = amount1 *-1, amount2 = amount2 *-1
    where field1 = <value>
    and field2 in ( Select filed2 from <table1> );
    Any idea why would this update not work? Has anyone faced this issue in Oracle 11g??
    Appreciate your suggestions & thanks in Advance for your inputs.
    Cheers,
    MS

    Update statement is something like this.
    Update <GTT>
    SET amount1 = amount1 *-1, amount2 = amount2 *-1
    where field1 = <value>
    and field2 in ( Select filed2 from <table1> );
    Any idea why would this update not work?
    You already told us that it DOES work - no errors or exceptions.
    It is trivial to determine if that update will do anything - just turn it into a SELECT and see if any rows are ntselected:
    v_cnt INTEGER;
    SELECT COUNT(*) INTO v_cnt FROM  myGTT
    WHERE field1 = <value>
    AND field2 in (Select field2 from <tablee1>);
    Then take a look at the 'count' that you get.

  • Global Temp Tables

    Has anyone had any luck using global temp tables within DI?  I am tryng to create a process that will populate a global tmp table in one data flow and then read from that global tmp table in the next data flow within the same work flow.  A template table won't work for my needs as I also need to be able to do a lookup_ext... is null from this table as well.
    There is a risk in using a physical temp table as this process will be ran many times through out the day with various values.
    Thanks,
    Alicia

    Within Oracle one can create a Global Temporary Table which is a database object; however, it clears it's contents when the session is released.  It is useful when creating reusable routines as multiple processes can write different information to the table and the table maintains the information for the life of the SQL session.  For instance one can populate the table with a list of codes to be used in a SQL statement for a product and run a seperate process simutaneously populating codes for a different product.
    The probelm I am having right now is that DI seems to be closing it's SQL session before it goes to the Data Flow that needs the code list.
    Thanks,
    Alicia

  • Global Temp tables in standy-by db

    Hi All,
    Can i use Global temp tables in a stand by database?
    The temp tables will be used for dml purpose.
    oracle version is 10g R2
    RHEL 5
    Thanks,
    Ajay Kumar

    Physical standby :
    No DMLs are allowed on the standby database and the most important things is that Standby databases can always be opened in READ-ONLY mode which won't allow DMLs.
    Logical standby :
    Logical standby database may have different structure from primary database. When it is in read-only mode SQL statements generated from redo are applied and queries may be run concurrently. When in read-write mode one can modify data in tables created in addition to primary schema. But this setting may be over written by specifying additional security options.
    http://oracleonline.info/standby_database_type.html
    http://download.oracle.com/docs/cd/B10500_01/server.920/a96653/manage_ls.htm
    Thanks

  • Can a tabular form be created/used against a GLOBAL TEMP TABLE?

    We are trying to simplify our apex applications. In doing so, we are examing the many collections we use to create tablular forms. These collections currently are tricky to manage and we are considering moving them to either VIEWS or GLOBAL TEMPORARY TABLES (GTT).
    I have created a test app against a GLOBAL TEMP TABLE....it looks great, but when I add a row and SUBMIT I recieve a message indicating record is inserted....but where did it go? I am unable to retrieve...I cannot see it in the underlying GLOBAL TEMP TABLE (as expected)....
    should I be creating an ON INSERT table on the GTT to automatically insert the data into a regular table?

    Now you know why you have to use collections :) Answered here:
    working with global temp table and apex
    Has to do with the session management and how APEX handles it.
    Create a view on your collection using the column names from the source table. Use packages to write an update, delete and insert process. This can be written automatically if there are multiple collections to handle.
    Denes Kubicek
    http://deneskubicek.blogspot.com/
    http://www.apress.com/9781430235125
    http://apex.oracle.com/pls/apex/f?p=31517:1
    http://www.amazon.de/Oracle-APEX-XE-Praxis/dp/3826655494
    -------------------------------------------------------------------

  • Use of Oracle global temp table in BI Publisher

    Hi All,
    I have witten a function which populates a Gobal temp table.I call the function and do a select on the global temp table.This fails to give me any result.
    We are calling the function within the package in the 'beforeReport' trigger in our Data Template in BI Publisher.
    I tried to check the session id and found that the sessions are different when we execute the functiona and when we do a select query.
    How can I avoid this situation of changing session?
    I have tried by removing commit from the function but even thta didnt help.
    Please let me know if anyone has suugestion on this.
    Thanks in advance!

    Hi,
    To check if the function is working fine , we inserted the output from temp table into a normal physical table .We queried the physical table and found the values there.
    So , the function is working fine.
    We dont have any statement like 'PRAGMA AUTONOMOUS_TRANSACTION ' in our function.
    Do we need to add it?
    Just to clarify the issue , We have populated the temp table by calling a function and after that we are trying to query the temp table.However, it appears that the session changes between teh function call and issuing of select query .This is resultin into no data being fetched as the values in Gloabal temp table persist only for a session.
    Thanks!

  • Global Temp Table Data Deleted Before Use

    Hi All,
    My application sends query to Procedure as input by using which data is inserted in Global Temp Table but when want to use inserted data in Application there are no records in table.
    There is no implicit or explicit Commit after data insertion. If I use ON COMMIT PRESERVE ROWS option during global table creation, still records are deleted from temp table .....Application don't gets records.
    What may be other reasons.
    Thanks in Advance.
    Rakesh-India

    bro u need to explicity use COMMIT for preserve transactions. the clause for the global temporary table states ON COMMIT; meaning if u commit ...got it now.
    explicitly commiting the transactions after insert worked.
    Now the global temp tab are session based, other user session cannot access the inserted rows.
    If commiting the transaction doesn't work then u should retrieve the inserted rows within the procedure or at the end of the proc code the data may be truncated... but commiting the transactions should work easily.
    zaibi.

  • ORA-04091: table name is mutating, trigger/function may not see it

    Hi,
    I have a row level before update trigger written on a table A which calls a procedure to undergo some processing. Procedure has some select queries against table A and it inturn causes the following error.
    ORA-04091: table name is mutating, trigger/function may not see it
    To overcome this I have used a combination of PL/SQL collection types (nested tables based on the following definition TYPE t_table_a is table of A.colname%TYPE index by binary_integer;), a row level before update trigger and statement level after update trigger. The mutating problem is fixed, but to update one row of data it took around 3 min and I am wondering if its the problem with PL/SQL tables I have used.
    In before update trigger I am storing the unique id's which needs to be updated into the PL/SQL table and in the after update trigger I am looping through the PL/SQL table and peforming the rest of the processing by calling in the procedure.
    Can anyone help how to minimize the run time of this process or if any other better solution exists?
    Thanks for the help

    Triggers raise the mutating table issue, because else they could be used to create endless loops. If you work around the mutating table issue, then you should make sure not to create an endless loop yourself. This would be possible.
    You description also seems to imply something like this.
    Without code it is impossible to say something specific.
    - Do you initialize your collection in a before statement trigger?
    - Is your looping mechanism somehow broken?
    - Do you update the same table again and again and again?

  • Is it possible to load and read from an Oracle global temp table?

    Is there a way to call an Oracle database package to pre-load global temp tables in BIP? I am an Oracle Reports user but a newbie to BIP. In Oracle Reports, I use the before-reports trigger to execute a database package that will populate a temp table with data. Then, in Oracle Reports, I read the temp table as the report data source. In BIP, I cannot find the ‘before-reports trigger’ equalivant. Since all the complicated business logic is contained in package it would be helpful to bring in the loaded temp table into BIP. Any thoughts?
    Example:
    Step 1. In the Oracle Reports before report trigger : exec db_package.load_temp_table_procedure (:var1, :var2, :var3);
    Step 2: Select * from temp_table.

    Look at Datatemplates,
    It has pre and post report trigger,
    You can do all these stuff over there,
    Calling a package  in Data template

  • Using Global Temporary Table in Discoverer.

    Hi All
    I am currently working on a Disco report, where I am initializing a package at the disco condition level which inserts data in to a Global Temporary Table.
    The global temporary table will be having data based on the parameter entered by the user. But the problem occurs when we are trying to use the same GTT in the select statement as shown below. The desktop is not giving me the otuput but the GTT is getting populated with data.
    see below
    SELECT bla1,
    bla2,
    bla3
    FROM GTT (global temp table)
    WHERE 1= PACKAGE.FUNCTION(par1, par2, par3...) <- here we are trying to insert into GTT based on the paramenters passed.
    Can you please suggest how this can be achieved. Or is there any way to trigger the insertion in to GTT other than the calling it in the condition level.
    Thanks
    Arun

    Hi,
    You cannot use a GTT like this because you cannot write and read from the GTT using a single SQL statement. You must either have the insert in a separate worksheet and tell the users to run this worksheet first, or you wrap it all up in a table function called from within a view. The table function can then insert and select from the GTT using two statements.
    Which method is best depends on what you are trying to do and why you want to use a GTT.
    Rod West

  • Multiple users accessing the same data in a global temp table

    I have a global temp table (GTT) defined with 'on commit preserve rows'. This table is accessed via a web page using ASP.NET. The application was designed so that every one that accessed the web page could only see their data in the GTT.
    We have just realized that the GTT doesn't appear to be empty as new web users use the application. I believe it has something to do with how ASP is connecting to the database. I only see one entry in the V$SESSION view even when multiple users are using the web page. I believe this single V$SESSION entry is causing only one GTT to be available at a time. Each user is inserting into / selecting out of the same GTT and their results are wrong.
    I'm the back end Oracle developer at this place and I'm having difficulty translating this issue to the front end ASP team. When this web page is accessed, I need it to start a new session, not reuse an existing session. I want to keep the same connection, but just start a new session... Now I'm losing it.. Like I said, I'm the back end guy and all this web/connection/pooling front end stuff is magic to me.
    The GTT isn't going to work unless we get new sessions. How do we do this?
    Thanks!

    DGS wrote:
    I have a global temp table (GTT) defined with 'on commit preserve rows'. This table is accessed via a web page using ASP.NET. The application was designed so that every one that accessed the web page could only see their data in the GTT.
    We have just realized that the GTT doesn't appear to be empty as new web users use the application. I believe it has something to do with how ASP is connecting to the database. I only see one entry in the V$SESSION view even when multiple users are using the web page. I believe this single V$SESSION entry is causing only one GTT to be available at a time. Each user is inserting into / selecting out of the same GTT and their results are wrong.
    I'm the back end Oracle developer at this place and I'm having difficulty translating this issue to the front end ASP team. When this web page is accessed, I need it to start a new session, not reuse an existing session. I want to keep the same connection, but just start a new session... Now I'm losing it.. Like I said, I'm the back end guy and all this web/connection/pooling front end stuff is magic to me.
    The GTT isn't going to work unless we get new sessions. How do we do this?
    Thanks!You may want to try changing your GTT to 'ON COMMIT DELETE ROWS' and have the .Net app use a transaction object.
    We had a similar problem and I found help in the following thread:
    Re: Global temp table problem w/ODP?
    All the best.

  • Inserting data in global temp table?

    Hello experts,
    i have a form having base table master and detail. i can insert upadate the records.
    requirement: creating the global temp table for same form. sothat data save only form session.
    for this i created 2 global temp table having same structure required for same form.
    i changes the property for block as base table to global temp table.
    now i am trying to save the records but not going in the temp table. as i changes the block base table property to temp tables
    as well as advance data block properties also .
    please tell me the reason? where can be the problem.
    thanks yash
    Edited by: yash_08031983 on Apr 16, 2012 1:27 AM

    i am trying to save the records but not going in the temp table.How do you check that? You cannot go to sqlplus and check if there are any records in the GTT. Data in a GTT is only visible in the current session (= only in the form).
    What is the use of a GTT here? What are you trying to achieve?

  • Global temp table and edit

    Hi all,
    Can someone tell me why when I create a GTT and insert the data like the followijng ,I get insert 14 rows msg. But when I do a select statement from sqlwork shop , sometimes i get the data sometimes I don't. my understanding is this data is supposed to stay during my logon session then got cleaned out when I exit session.
    I am developing a screen in apex and will use this temp table for user to do some editing work. Once ithe editing is done then I save the data into a static table. Can this be done ? So far my every attempt to update the temp table always result to 0 rows updated and the temp table reversed back to 0 rows. CAn you help me ?
    CREATE GLOBAL TEMPORARY TABLE "EMP_SESSION"
    (     "EMPNO" NUMBER NOT NULL ENABLE,
         "ENAME" VARCHAR2(10),
         "JOB" VARCHAR2(9),
         "MGR" NUMBER,
         "HIREDATE" DATE,
         "SAL" NUMBER,
         "COMM" NUMBER,
         "DEPTNO" NUMBER
    ) ON COMMIT PRESERVE ROWS
    insert into emp_session( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
    select * from emp
    select * from emp_session
    -- sometimes I get 14 rows, sometimes 0 rows
    Thanks.
    Tai

    Tai,
    To say that Apex doesn't support GTT's is not quite correct. In order to understand why it is not working for you and how they may be of use in an Apex application, you have to understand the concept of a session in Apex as opposed to a conventional database session.
    In a conventional database session, as when you are connected with sqlplus then you have what is known as a dedicated session, or a synchronous connection. Temporary objects such as GTTs and packaged variables can persist across calls to the database. A session in Apex however is asynchronous by nature and a connection to the database is done through some sort of a server such as the Oracle HTTP server or the Apex Listener, which in effect maintains a pool of connections to the database and calls by your application aren't guaranteed to get the same connection for each call.
    To get over this, the guys who developed Apex came up with various methods to maintain session state and global objects that are persistent within the context of an Apex session. One of these is Apex collections, which are a device for maintaining collection like (array like) data that is persistent within an Apex session. These are Apex session specific objects in that they are local to the session that creates and maintains them.
    With this knowledge, you can then see why the GTT is not working for you and also how a GTT may be of use in an Apex application, provided you don't expect the data to persist across a call, as in a PL/SQL procedure. You should note though, that unless you are dealing with very large datasets, then a regular Oracle collection is preferable.
    I hope this explains your issue.
    Regards
    Andre

Maybe you are looking for