View and Instead of trigger

Hi !
In my application I have two tables
tabA(col_A1,col_A2,col_A3) and tabB(col_B1,col_B2)I created a view
CREATE OR REPLACE VIEW  vt
AS SELECT  col_A1, col_A2, col_A3, col_B1, col_B2
     FROM  tabA  A
             LEFT OUTER JOIN  tabB  B
               ON (        A.ol_Achar = B.col_Bchar
                   OR 'A'||A.ol_Achar = B.col_Bchar ); and an instead of trigger
CREATE OR REPLACE TRIGGER vt_upd
  INSTEAD OF UPDATE ON vt
BEGIN
  UPDATE    tabA
     SET    col_A3 = :NEW.col_A3
     WHERE  col_A1 = :NEW.col_A1;
END;
/And now there are very strange behaviours on an update statement I've tried:
UPDATE vt SET col_A3=1 where col_A1=2;1.) If I try it on an Oracle instance version 10.2.0.1.0 it's OK, the update (and hence the instead of triggers) does the right thing.
2.) If I try it on an Oracle instance version 9.2.0.7.0 I get an error:
ORA-01031: insufficient privileges3.) If I change the the definition to:
CREATE OR REPLACE VIEW  vt
AS SELECT  col_A1, col_A2, col_A3, col_B1, col_B2
     FROM  tabA  A
             LEFT OUTER JOIN  tabB  B
               ON A.ol_Achar = B.col_Bchar;the update will work on 9.2.0.7.0 as well.
Any idea why there are such troubles ?
Thanks for any help,
Heinz

Don't have 9.2.0.7 at hand and your view definition is a bit screwed. But what I tried was
michaels>  create table taba(col_a1 varchar2(5),col_a2 varchar2(5),col_a3 varchar2(5))
Table created.
michaels>  create table tabb(col_b1 varchar2(5),col_b2 varchar2(5))
Table created.
michaels>  create or replace view vt
as
   select col_a1, col_a2, col_a3, col_b1, col_b2
     from taba a left outer join tabb b
          on (a.col_a1 = b.col_b1 or 'A' || a.col_a2 = b.col_b2)
View created.
michaels>  create or replace trigger vt_upd
   instead of update
   on vt
begin
   update taba
      set col_a3 = :new.col_a3
    where col_a1 = :new.col_a1;
end vt_upd;
Trigger created.
michaels>  update vt
   set col_a3 = 1
where col_a1 = 2
0 rows updated.
michaels>  select * from v$version
BANNER                                                         
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
PL/SQL Release 9.2.0.8.0 - Production                          
CORE     9.2.0.8.0     Production                                      
TNS for HPUX: Version 9.2.0.8.0 - Production                   
NLSRTL Version 9.2.0.8.0 - Production Maybe time to upgrade?

Similar Messages

  • Storing XML using XSU, object VIEW and INSTEAD OF trigger

    Here is the point:
    I've got 2 tables which are linked:
    CREATE TABLE dept (
    deptno NUMBER PRIMARY KEY,
    deptname VARCHAR2(20)
    CREATE TABLE emp (
    empno NUMBER PRIMARY KEY,
    empname VARCHAR2(20),
    deptno NUMBER REFERENCES dept(deptno)
    I've got the following message, which I want to insert in the tables using XSU (I already have a PL/SQL stored procedure which work perfectly for insertion into 1 table, using DBMS_XMLSave.insertXML or xmlgen.insertXML):
    <DEPT>
    <DEPTNO>10</DEPTNO>
    <DEPTNAME>IT</DEPTNAME>
    <EMP>
         <EMPNO>1</EMPNO>
         <EMPNAME>John</EMPNAME>
    </EMP>
    <EMP>
         <EMPNO>1</EMPNO>
         <EMPNAME>Phil</EMPNAME>
    </EMP>
    </DEPT>
    So I've created the following object:
    CREATE TYPE emp_t AS OBJECT
    empno NUMBER,
    empname VARCHAR2(20)
    CREATE TYPE emplist_t AS TABLE OF emp_t;
    CREATE TYPE dept_t AS OBJECT
    deptno NUMBER,
    deptname VARCHAR2(20),
    emplist emplist_t
    Now I understand that I should create an object VIEW and an INSTEAD OF trigger (That's what I read many times),
    but I don't know how to structure the view and the trigger.
    Could you help? (Example of a similar context, piece of code)
    Thanks a lot
    Marion

    Hi John,
    I have exactly the same issue as you experienced back in January. I have a complex data modelling requirement which requires the need to pivot rows into columns using ROW_NUMBER() and PARTITION clauses. To hide the complexity from the middle tier, I have created a database view and appropriate INSTEAD OF triggers and mapped my EO to the view. I have overriden the lock() method on the EO implementation class (to avoid ORA-02014) and would like to try the same solution you used with the pl/sql call to lock the record.
    My question is, how did you manage the release of the lock if the transaction was not rolled back or committed by your application i.e. if the user closed the browser for instance.
    In my naivity, I would like to think that the BC4J framework would release any locks for the database session when it found the servlet session to be terminated however my concern is that the lock would persist and cause complications.
    Any assistance greatly appreciated (if you would be willing to supply your lock() method and pl/sql procedure logic I would be even more grateful!).
    Many thanks,
    Dave
    London

  • Form with view having instead-of-trigger gives FRM-40501 and ORA-02014

    I created a data-entry from with a 'view' as datas-source block. This view gives crosstab query results with a data from a single base-table but it is complex and uses decode and aggregate funciton 'max' just to create group by in a crosstab query. I have created a instead of trigger on this view to update or insert a record in base table. A test to update base table works fine at SQl prompt. A test to insert at SQL shows '1 row created' but in fact when I query the database, it does not show newly inserted row. Also, when I compile and run this form, I get FRM-40501 and ORA-02014. Help!!!
    I know that DML operations on a view with DECODE, aggregate functions or group by can not be performed but I thought the "instead of" trigger on the view to update the base table should eleminate this restriction and hence pusued further but now stuck!
    BTW: I can post details of base table, view, and instead of trigger, if you want to see them to further decipher the problem. Just let me know. Thanks!
    VERSIONS: Forms in developer suite v10.1.2.0.2 on Windows XP 64 bit desktop - ; Backend database: 9.2.0.8 on Windows 2003 EE server
    Edited by: user8647268 on Aug 19, 2009 1:19 PM
    Edited by: user8647268 on Aug 19, 2009 1:25 PM

    I just forgot to ask you one question: In my experience with forms, I have captured before_value and after_value and implemented logic based on results many times. This form I am working on is kinda first multi-record form where I have a tabular page with date and about 7 other columns forming a grid of cells, which users wanted. Each line is a record from a view. I tried relying on forms to do DML on underlying table and since the underlying table is a paritioned table, I ran into FRM-40509 and ORA-00936, where returning ROWID becomes problematic. I found a note 167550.1 which says to set Key mode to 'Updateable' or 'Non-Updateable' but not 'Unique' or 'Automatic' as a solution #1. Solution#1 failed i.e. the errors persisted. The note also says in that case, implement Solution #2, which is to write explicit trigger to do each of the DML on view. Here I run into kinda problem: In a tabular form with say 31 records each row having 7 cells which is like capturing 217 before values..that is too many. Addressing them with ':old.xxx' or ':new.xxx' which works in instead of trigger, does not work in trigger inside forms. Without checking these before and after values, it inserts rows with nulls for empty cells where we wnated it to skip and do nothing. So iam looking for a way to capture before value using some kinda standard form mechanism..Do you have any suggestions! (Sorry for long explanation but that is the only way to do it..)

  • Issue in Invoking an Updatable View with Instead of Trigger

    Hi,
    I am trying to insert a record using Updatable View with Instead of Trigger. When i try to save the data, i get the below error:
    java.sql.SQLException: ORA-01403: no data found
    ORA-06512: at line 1
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:457)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:405)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:889)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:476)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:204)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:540)
    at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:213)
    at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1075)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1466)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3752)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3887)
    at oracle.jdbc.driver.OracleCallableStatement.executeUpdate(OracleCallableStatement.java:9323)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1508)
    at weblogic.jdbc.wrapper.PreparedStatement.executeUpdate(PreparedStatement.java:172)
    at oracle.jbo.server.OracleSQLBuilderImpl.doEntityDML(OracleSQLBuilderImpl.java:432)
    at oracle.jbo.server.EntityImpl.doDMLWithLOBs(EntityImpl.java:8566)
    Can someone help me resolve this issue?
    Also it would be great if you can share Sample codes for Invoking an updatable view with instead of trigger on Save/commit.
    Regards,
    Jeevan

    As a trigger is executed in the db and not in your app it's really hard to help as you did not give any useful information.
    Have you read this blog http://stegemanoracle.blogspot.com/2006/03/using-updatable-views-with-adf.html ?
    Timo
    Edited by: Timo Hahn on 22.09.2011 09:15
    And my friend google also found http://technology.amis.nl/blog/1447/adf-business-components-resfresh-after-insertupdate-and-instead-of-triggers

  • How to create ADF BC components like EO from  "View with INSTEAD OF trigger

    I have a "View with INSTEAD OF trigger" on a external schema. is it possible to create ADF EO on top of this view in my local schema?. If possible, then is it possible to insert/update that external table using ADF standard data controls and Application module?. I'm trying to see if it's possible with standard ADF controls without calling pl/sql API to insert/update that external table. any ideas are appreciated.
    Regards,
    Surya

    http://stegemanoracle.wordpress.com/2006/03/15/using-updatable-views-with-adf/

  • BULK INSERT into View w/ Instead Of Trigger - DML ERROR LOGGING Issue

    Oracle 10.2.0.4
    I cannot figure out why I cannot get bulk insert errors to aggregate and allow the insert to continue when bulk inserting into a view with an Instead of Trigger. Whether I use LOG ERRORS clause or I use SQL%BULK_EXCEPTIONS, the insert works until it hits the first exception and then exits.
    Here's what I'm doing:
    1. I'm bulk inserting into a view with an Instead of Trigger on it that performs the actual updating on the underlying table. This table is a child table with a foreign key constraint to a reference table containing the primary key. In the Instead of Trigger, it attempts to insert a record into the child table and I get the following exception: +5:37:55 ORA-02291: integrity constraint (FK_TEST_TABLE) violated - parent key not found+, which is expected, but the error should be logged in the table and the rest of the inserts should complete. Instead the bulk insert exits.
    2. If I change this to bulk insert into the underlying table directly, it works, all errors get put into the error logging table and the insert completes all non-exception records.
    Here's the "test" procedure I created to test my scenario:
    View: V_TEST_TABLE
    Underlying Table: TEST_TABLE
    PROCEDURE BulkTest
    IS
    TYPE remDataType IS TABLE of v_TEST_TABLE%ROWTYPE INDEX BY BINARY_INTEGER;
    varRemData remDataType;
    begin
    select /*+ DRIVING_SITE(r)*/ *
    BULK COLLECT INTO varRemData
    from TEST_TABLE@REMOTE_LINK
    where effectiveday < to_date('06/16/2012 04','mm/dd/yyyy hh24')
    and terminationday > to_date('06/14/2012 04','mm/dd/yyyy hh24');
    BEGIN
    FORALL idx IN varRemData.FIRST .. varRemData.LAST
    INSERT INTO v_TEST_TABLE VALUES varRemData(idx) LOG ERRORS INTO dbcompare.ERR$_TEST_TABLE ('INSERT') REJECT LIMIT UNLIMITED;
    EXCEPTION WHEN others THEN
    DBMS_OUTPUT.put_line('ErrorCode: '||SQLCODE);
    END;
    COMMIT;
    end;
    I've reviewed Oracle's documentation on both DML logging tools and neither has any restrictions (at least that I can see) that would prevent this from working correctly.
    Any help would be appreciated....
    Thanks,
    Steve

    Thanks, obviously this is my first post, I'm desperate to figure out why this won't work....
    This code I sent is only a test proc to try and troubleshoot the issue, the others with the debug statement is only to capture the insert failing and not aggregating the errors, that won't be in the real proc.....
    Thanks,
    Steve

  • ADF BC: Creating updatable VO based upon DB View with "instead of" trigger

    Hello all,
    I have got an interesting issue. I have an Oracle DB view that is used to hide some complexity in the underlying DB design (it does some unions). This view is updatable because we have created an "instead of" update trigger to update the correct table when a row is updated. This is working fine in SQL.
    Next, we have created an ADF Entity object based upon the view, specifying an appropriate PK for the DB View. Then, we have created an updatable VO based upon the EO. All well and good so far. The issue we have is in trying to commit changes to the DB - because the ADF BC framework is trying to lock the row to update (using SELECT ... FOR UPDATE), it's not working because of ORA-02014 - cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc.
    This leads me to thinking about overridding doSelect() on the EO as hinted here http://radio.weblogs.com/0118231/stories/2005/07/28/differenceBetweenViewObjectSelectAndEntityDoselectMethod.html
    As a temporary test, we have over-ridden the EO's doSelect to call super.doSelect(false) and it does work, although we will have lost update issues as detailed in Steve's article.
    My questions:
    1). Is overriding doSelect() the correct thing here? Perhaps there is a better way of handling this problem? I do have a base EO class from which all of the EO's extend, so adding this behavior should be straightforward.
    2). Does anyone have example doSelect implementation? I am thinking of overriding doSelect for my EO and calling super.doSelect (lock=false), but then I need to deal with some possible exceptions, no?
    Kind regards,
    John

    Hi John,
    I have exactly the same issue as you experienced back in January. I have a complex data modelling requirement which requires the need to pivot rows into columns using ROW_NUMBER() and PARTITION clauses. To hide the complexity from the middle tier, I have created a database view and appropriate INSTEAD OF triggers and mapped my EO to the view. I have overriden the lock() method on the EO implementation class (to avoid ORA-02014) and would like to try the same solution you used with the pl/sql call to lock the record.
    My question is, how did you manage the release of the lock if the transaction was not rolled back or committed by your application i.e. if the user closed the browser for instance.
    In my naivity, I would like to think that the BC4J framework would release any locks for the database session when it found the servlet session to be terminated however my concern is that the lock would persist and cause complications.
    Any assistance greatly appreciated (if you would be willing to supply your lock() method and pl/sql procedure logic I would be even more grateful!).
    Many thanks,
    Dave
    London

  • View with Instead of Trigger - ORA-01031

    I am having trouble with a form based on a view that uses an instead of trigger.
    When I attempt to update a complex view that uses instead of triggers in an APEX form, I get the following message:
    ORA-20001: Error in DML: p_rowid=21388, ... ORA-01031: insufficient privileges
    The view works correctly when updates are executed from SQL Plus.
    The view "VW" is based on several tables in the application schema "X", which is parsed by APEX, and several tables in another schema "Z". I have explicitly granted select permission on the tables in schema "Z" to schema "X", but this doesn't resolve the error.
    Any idea how to fix this problem? From reading other posts, it sounds like the only issue should be explicit grants on the tables in other schemas. I do not attempt to update the tables in schema "Z", and do not have update permissions to those tables.
    Sinerely, Justin

    Justin,
    you might try to grant the views to the FLOWS_xxxxx user, which performs the Apex processes.
    Dik Dral

  • View with instead of trigger still not updatable

    Hi everybody,
    could somebody explain how to make this view updatable?
    I have the following log:
    CREATE OR REPLACE FORCE VIEW BRS_V_VERPLICHTINGEN
    (VERPLICHTING_NR
    ,ONTSTAANSJAAR
    ,OMSCHRIJVING
    ,DATUM_VERANTWOORDING
    ,OBJECT_NR
    ,OBJECT_NAAM
    ,CDG_CODE
    ,TMA_CODE
    ,CREATED_BY
    ,CREATION_DATE
    ,LAST_UPDATED_BY
    ,LAST_UPDATE_DATE)
    AS SELECT vw_brs_verplichting.verplichting_nr
    ,     vw_brs_verplichting.ontstaansjaar
    ,     nvl( brs_verplichtingen.omschrijving, vw_brs_verplichting.verplichting_oms
    ,     vw_brs_verplichting.datum_verantwoording
    ,     vw_brs_verplichting.object_nr
    ,     vw_brs_verplichting.object_naam
    , brs_verplichtingen.cdg_code
    ,     brs_verplichtingen.tma_code
    ,     brs_verplichtingen.created_by
    ,     brs_verplichtingen.creation_date
    ,     brs_verplichtingen.last_updated_by
    ,     brs_verplichtingen.last_update_date
    FROM vw_brs_verplichting
    ,     brs_verplichtingen
    WHERE vw_brs_verplichting.vervallen_code = 'N'
    AND vw_brs_verplichting.verplichting_nr = brs_verplichtingen.verplichting_nr
    AND vw_brs_verplichting.ontstaansjaar = brs_verplichtingen.ontstaansjaar
    View created
    CREATE OR REPLACE TRIGGER BRS_VVG_IRU
    INSTEAD OF UPDATE
    ON BRS_V_VERPLICHTINGEN
    BEGIN
    brs_vvg_pck.instead_of_row_update( :new.verplichting_nr
    , :new.ontstaansjaar
    , :new.omschrijving
    , :new.cdg_code
    , :new.tma_code
    END ;
    Trigger created
    SELECT COLUMN_NAME
    ,     INSERTABLE
    ,     UPDATABLE
    ,     DELETABLE
    FROM USER_UPDATABLE_COLUMNS
    WHERE TABLE_NAME = 'BRS_V_VERPLICHTINGEN'
    COLUMN_NAME INSERTABLE UPDATABLE DELETABLE
    VERPLICHTING_NR YES YES YES
    ONTSTAANSJAAR YES YES YES
    OMSCHRIJVING NO NO NO
    DATUM_VERANTWOORDING YES YES YES
    OBJECT_NR YES YES YES
    OBJECT_NAAM NO YES NO
    CDG_CODE NO YES NO
    TMA_CODE NO YES NO
    CREATED_BY NO YES NO
    CREATION_DATE NO YES NO
    LAST_UPDATED_BY NO YES NO
    LAST_UPDATE_DATE NO YES NO
    12 rows selected
    But that one column still isn't updatable... however because i'm using an INSTEAD OF UDPATE trigger they should all be updatable, shouldn't they?
    I'm using the 10g database...
    Hope someone can help...
    Regards,
    Robert

    Justin,
    you might try to grant the views to the FLOWS_xxxxx user, which performs the Apex processes.
    Dik Dral

  • ERROR - 16016 - FOR FORM CREATED ON A VIEW AND USING INSTEAD OF TRIGGER

    I have created a form based on a view. The view has instead of Trigger on it.
    When I try to update the form I get the following error:
    Error: An unexpected error occurred: ORA-22816: unsupported feature with RETURNING clause (WWV-16016)
    Can anyone tell what the problem is?
    Thanks
    null

    THANKS A LOT IT WORKED.
    <BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by Rene' Castle ([email protected]):
    This is a bug with views. If you can edit the PL/SQL code that is generated, you can remove the RETURNING clause and it will work.
    NOTE: This will have to be done every time you edit the form.
    <HR></BLOCKQUOTE>
    null

  • Instead of trigger and merge

    Hi,
    I have created view and instead of insert, delete, update triggers on it. It is working fine for insert, delete, update. However, the application uses lots of merge command. For merge command on the view, I get following error
    ORA-01446: cannot select ROWID from, or sample, a view with DISTINCT, GROUP BY, etc.
    I dont have any rowid mentioned in merge command. Is there way how to make MERGE working over view with instead of triggers ?
    Thanks for advices.

    my view is simple, it is "union all" operation over several tables without any other conditions, original tables are index organized with PK consisting of 4 columns
    EDIT:
    here is simplified example of the problem
    create table val_00 (
    id number(10),
    data varchar2(100),
    constraint pk_val_00 primary key (id) validate
    ) organization index;
    create table val_01 (
    id number(10),
    data varchar2(100),
    constraint pk_val_01 primary key (id) validate
    ) organization index;
    create or replace view val as
    select id, data from (
    select id, data from val_00
    union all
    select id, data from val_01
    create or replace trigger trg_val_ins
    instead of insert on val
    referencing new as new
    for each row
    begin
    case mod(:new.id, 2)
    when 0 then insert into val_00 (id, data) values (:new.id, :new.data);
    when 1 then insert into val_01 (id, data) values (:new.id, :new.data);
    end case;
    end;
    create or replace trigger trg_val_upd
    instead of update on val
    referencing old as old new as new
    for each row
    begin
    if updating('id') then
    raise_application_error(-20999, 'you can not update primary key in val');
    end if;
    case mod(:new.id, 2)
    when 0 then update val_00 set data = :new.data where id = :old.id;
    when 1 then update val_01 set data = :new.data where id = :old.id;
    end case;
    end;
    create or replace trigger trg_val_del
    instead of delete on val
    referencing old as old
    for each row
    begin
    case mod(:old.id, 2)
    when 0 then delete from val_00 where id = :old.id;
    when 1 then delete from val_01 where id = :old.id;
    end case;
    end;
    insert into val values (1, 'one');
    insert into val values (2, 'two');
    insert into val values (3, 'three');
    insert into val values (4, 'four');
    insert into val values (5, 'five');
    delete from val where id = 2;
    insert into val values (2, 'twooo');
    update val set data = 'two' where id = 2;
    commit;
    merge into val using
    ( select 10 as id, 'ten' as data from dual ) newdata
    on (val.id = newdata.id)
    when matched then
    update set val.data = newdata.data
    when not matched then
    insert (id, data) values (newdata.id, newdata.data);
    ERROR at line 1:
    ORA-01446: cannot select ROWID from, or sample, a view with DISTINCT, GROUP BY, etc.
    Edited by: kamilp on Aug 18, 2012 8:17 AM

  • Instead of trigger on view with CLOB data

    I have writed Instead of trigger for view "article(id,text)" with CLOB
    field "text".
    create or replace trigger v_article_insert
    instead of insert on v_article
    for each row
    declare
    begin
    insert into article(id,text) values(id,:new.text);
    end v_article_insert;
    When I try to do DML (insert, update), forexample:
    insert into v_article(text) values('bla-bla')
    I get:
    ORA-25008 no implicit conversion to LOB datatype in instead-of trigger.
    ( Cause: When inserting or updating a view using instead-of trigger, the
    new value for a LOB view column is of a different datatype.
    Action: Specified a LOB value as the new value for the LOB view
    column.)
    insert into v_article(text) values(empty_clob()) - It works...
    What does it mean and what is right syntax for DML for CLOB fields in
    instead of triggers?

    When inserting CLOBs you create the row with an Empty_Clob() to initialize the CLOB field. Then you can update the empty CLOB with your CLOB value.
    The error message is telling you that Oracle will not convert your CLOB to the initialization value needed.

  • Issue using an INSTEAD OF trigger

    Hi Guys,
    I've not posted in here before so please tell me if i'm asking too much or just not doing something right.
    I have created the following view which will compile ok:
    DROP VIEW book_cust_vu;
    CREATE VIEW book_cust_vu AS
    SELECT c.cust_id, c.name, c.tel_no, b.table_no, b.book_date, b.time, b.book_id, b.notes, b.rest_id
    FROM booking b, customer c
    WHERE c.cust_id = b.cust_id;
    I am trying to create and INSTEAD OF trigger that will not allow an update to occur that matches and existing combination of b.table_no, b.rest_id and b.book_date. I have come up with the following:
    CREATE OR REPLACE TRIGGER book_chk
    INSTEAD OF UPDATE ON book_cust_vu
    FOR EACH ROW
    DECLARE
    tableno               book_cust_vu.table_no%TYPE;
    bookdate          book_cust_vu.book_date%TYPE;
    restid               book_cust_vu.rest_id%TYPE;     
    BEGIN
    SELECT table_no, book_date, rest_id
    INTO tableno, bookdate, restid
    FROM book_cust_vu
    WHERE book_id = :new.book_id;
    DBMS_OUTPUT.PUT_LINE('rest_id = '||restid);
    DBMS_OUTPUT.PUT_LINE('table_no = '||tableno);
    DBMS_OUTPUT.PUT_LINE('book_date = '||bookdate);
    IF :new .table_no != tableno AND
    :new.book_date != bookdate AND
    :new.rest_id != restid THEN
    UPDATE booking
    SET table_no = :new.table_no,
    book_date = :new.book_date,
    time = :new.time,
    notes = :new.notes,
    rest_id = :new.rest_id,
    book_id = :new.book_id
    WHERE book_id = :new.book_id;
    ELSE
    DBMS_OUTPUT.PUT_LINE('This booking matches an existing one');
    END IF;
    END;
    The DBMS outputs confirm that the variables are being populated with values that math existing combinations of those records, but the statement:
    IF :new .table_no != tableno AND
    :new.book_date != bookdate AND
    :new.rest_id != restid THEN
    does not seem to find this combination. The last DBMS output will also print, so that seems to confirm that the above statement is working in part, as DBMS output should only appear if the first IF statement is false. So basically, it will allow duplicates of the table_no, book_date, rest_id combo.
    This is my test update line:
    UPDATE book_cust_vu SET table_no = '1', rest_id = '1', book_date = '30-OCT-05' WHERE book_id = 3;
    The combination of values for table_no, book_date, rest_id already exist for another record.
    I have run out of ideas and simply comparing :new.variable != :old.variable will also allow the update to occur.
    If anyone can spot what is wrong or anything I need to change, that would be really helpful!!!
    Thanks,
    Anton

    Hi,
    Thanks for the suggestions guys, managed to get it going with a cursor instead:
    CREATE OR REPLACE TRIGGER book_chk
    INSTEAD OF UPDATE ON book_cust_vu
    FOR EACH ROW
    DECLARE
    temp          NUMBER;
    CURSOR book_count IS
    SELECT count(*)
    INTO temp
    FROM book_cust_vu
    WHERE book_date = :new.book_date
    AND table_no = :new.table_no
    AND rest_id = :new.rest_id;
    BEGIN
    OPEN book_count;
    LOOP
    FETCH book_count INTO temp;
    EXIT WHEN book_count%NOTFOUND;
    IF(temp = 1) THEN
    RAISE_APPLICATION_ERROR(-20012,
         'This booking matches an existing one');
    ELSE
    UPDATE booking
    SET table_no = :new.table_no,
    book_date = :new.book_date,
    time = :new.time,
    notes = :new.notes,
    rest_id = :new.rest_id,
    book_id = :new.book_id
    WHERE book_id = :new.book_id;
    END IF;
    END LOOP;
    CLOSE book_count;
    END;
    Worked on the first test, but we'll see!

  • View, instead of trigger and ORA-01031

    Hello,
    I have a view based on outer joins like
    CREATE VIEW vt ( colV1, colV2, colV3, colV4, colV5, colV6, colV7, colV8 ) AS
    SELECT A.colA1, A.colA2, C.colB0, B.colB2, B.colB3, B.colB4, C.colC2, H.colH2
      FROM  tabA    A
           ,tabB    B
           ,tabC    C
           ,( SELECT  ...
                FROM   tabD  D
                      ,tabE  E
                WHERE  D.colD1 = E.colE1
             )  H                                
      WHERE A.colA1 = B.colB1
        AND LTRIM(B.colB2,'A') = LTRIM(C.colC1(+),'A')    
        AND B.colB3 = H.colH1(+); and an instead of trigger
    CREATE OR REPLACE TRIGGER vt_upd
      INSTEAD OF UPDATE ON vt
    BEGIN
      UPDATE    tabB
         SET    colB4 = :NEW.colV6
         WHERE  colB0 = :NEW.colV2;
    END;An now the problem: an update statement UPDATE vt set colV6=1 WHERE colV1=1; in SQL*Plus works as it should, but performing an update in APEX from a tabular or edit form shows an error: ORA-01031:ORA-01031: insufficient privileges, update...The strange thing: in both sessions there is the same user USER1 logged on !
    Why this difference ? Can anybody explain ?
    Regards,
    Heinz

    Hi Heinz,
    Your statement -
    what I wrote as table tabC in reality is a view to one table and one view in another schema.That'll be it, you need to grant explicit rights for the objects in that schema to the schema that is your parsing schema for your workspace.
    In other words, if you have -
    1) Workspace 'A' with parsing schema 'B'
    and you are trying to do -
    select foo from c.bar
    i.e. you're trying to query an object in schema 'C'.
    Then you need to (as a DBA or connected to schema C) -
    grant select on bar to b;Roles won't work (when used through APEX)...I can't say that any other way, you might find it works in SQLPlus with roles, but through APEX it won't...you need those explicit grants.
    Hope this makes sense.
    John.

  • Instead of trigger example - INSERT works but UPDATE and DELETE does not?

    Below is a demostration script of what I am trying to troubleshoot. Tests are done on 10gR2;
    conn system/system
    drop table tt purge ;
    create table tt nologging as select * from all_users ;
    alter table tt add constraint pk_tt_user_id primary key (user_id) nologging ;
    analyze table tt compute statistics for table for all indexed columns ;
    conn hr/hr
    drop database link dblink ;
    create database link dblink
    connect to system identified by system
    using 'xe.turkcell' ;
    select * from global_name@dblink ;
    drop view v_tt ;
    create view v_tt as select username, user_id, created from tt@dblink order by 2 ;
    select count(*) from v_tt ;
    COUNT(*)
    13
    drop sequence seq_pk_tt_user_id ;
    create sequence seq_pk_tt_user_id
    minvalue 1000 maxvalue 99999
    increment by 1;
    create synonym tt for tt@dblink ;
    CREATE OR REPLACE PROCEDURE prc_update_tt(old_tt v_tt%ROWTYPE, new_tt v_tt%ROWTYPE) IS
    BEGIN
    IF old_tt.user_id != new_tt.user_id THEN
    RETURN; -- primary key
    END IF;
    IF old_tt.user_id IS NOT NULL AND new_tt.user_id IS NULL THEN
    DELETE FROM tt
    WHERE user_id = nvl(old_tt.user_id,
    -99);
    RETURN;
    END IF;
    IF (old_tt.username IS NULL AND new_tt.username IS NOT NULL) OR
    (old_tt.username IS NOT NULL AND new_tt.username != old_tt.username) THEN
    UPDATE tt
    SET username = new_tt.username
    WHERE user_id = nvl(old_tt.user_id,
    -99);
    END IF;
    IF (old_tt.created IS NULL AND new_tt.created IS NOT NULL) OR
    (old_tt.created IS NOT NULL AND new_tt.created != old_tt.created) THEN
    UPDATE tt
    SET created = new_tt.created
    WHERE user_id = nvl(old_tt.user_id,
    -99);
    END IF;
    END prc_update_tt;
    CREATE OR REPLACE PROCEDURE prc_insert_tt(old_tt v_tt%ROWTYPE, new_tt v_tt%ROWTYPE) IS
    new_tt_user_id NUMBER;
    BEGIN
    SELECT seq_pk_tt_user_id.NEXTVAL INTO new_tt_user_id FROM dual;
    INSERT INTO tt
    (username, user_id, created)
    VALUES
    (new_tt.username, new_tt_user_id, new_tt.created);
    END prc_insert_tt;
    CREATE OR REPLACE PROCEDURE prc_delete_tt(old_tt v_tt%ROWTYPE, new_tt v_tt%ROWTYPE) IS
    BEGIN
    DELETE FROM tt
    WHERE user_id = nvl(old_tt.user_id,
    -99);
    END prc_delete_tt;
    CREATE OR REPLACE TRIGGER trg_iof_v_tt
    INSTEAD OF UPDATE OR INSERT OR DELETE ON v_tt
    FOR EACH ROW
    DECLARE
    new_tt v_tt%ROWTYPE;
    old_tt v_tt%ROWTYPE;
    BEGIN
    dbms_output.put_line('INSTEAD OF TRIGGER fired');
    dbms_output.put_line(':NEW.user_id ' || :NEW.user_id);
    dbms_output.put_line(':OLD.user_id ' || :OLD.user_id);
    dbms_output.put_line(':NEW.username ' || :NEW.username);
    dbms_output.put_line(':OLD.username ' || :OLD.username);
    dbms_output.put_line(':NEW.created ' || :NEW.created);
    dbms_output.put_line(':OLD.created ' || :OLD.created);
    new_tt.user_id := :NEW.user_id;
    new_tt.username := :NEW.username;
    new_tt.created := :NEW.created;
    old_tt.user_id := :OLD.user_id;
    old_tt.username := :OLD.username;
    old_tt.created := :OLD.created;
    IF inserting THEN
    prc_insert_tt(old_tt,
    new_tt);
    ELSIF updating THEN
    prc_update_tt(old_tt,
    new_tt);
    ELSIF deleting THEN
    prc_delete_tt(old_tt,
    new_tt);
    END IF;
    END trg_iof_v_tt;
    set serveroutput on
    set null ^
    insert into v_tt values ('XXX', -1, sysdate) ;
    INSTEAD OF TRIGGER fired
    :NEW.user_id -1
    :OLD.user_id
    :NEW.username XXX
    :OLD.username
    :NEW.created 30/01/2007
    :OLD.created
    1 row created.
    commit ;
    select * from v_tt where username = 'XXX' ;
    USERNAME USER_ID CREATED
    XXX 1000 31/01/2007          <- seems to be no problem with insert part but
    update v_tt set username = 'YYY' where user_id = 1000 ;
    INSTEAD OF TRIGGER fired
    :NEW.user_id
    :OLD.user_id
    :NEW.username YYY
    :OLD.username
    :NEW.created
    :OLD.created
    1 row updated.
    commit ;
    select count(*) from v_tt where username = 'YYY' ;
    COUNT(*)
    0               <- here is my first problem with update part, Oracle said "1 row updated."
    delete from v_tt where user_id = 1000 ;
    INSTEAD OF TRIGGER fired
    :NEW.user_id
    :OLD.user_id
    :NEW.username
    :OLD.username
    :NEW.created
    :OLD.created
    1 row deleted.
    commit ;
    select count(*) from v_tt ;
    COUNT(*)
    14               <- here is my second problem with delete part, Oracle said "1 row deleted."
    Any comments will be welcomed, thank you.
    Message was edited by:
    TongucY
    changed "-1" values to "1000" in the where clause of delete and update statements.
    it was a copy/paste mistake, sorry for that.

    What table do you process in your procedures ? You don't use DBLINK to
    reference remote table in your procedures.
    Seems, you have table "TT" in "HR" schema too.
    Look:
    SQL> create table tt nologging as select * from all_users where rownum <=3;
    Table created.
    SQL> select * from tt;
    USERNAME                          USER_ID CREATED
    SYS                                     0 25-APR-06
    SYSTEM                                  5 25-APR-06
    OUTLN                                  11 25-APR-06
    SQL> conn scott/tiger
    Connected.
    SQL> create database link lk65 connect to ... identified by ... using 'nc65';
    Database link created.
    SQL> select * from tt@lk65;
    USERNAME                          USER_ID CREATED
    SYS                                     0 25-APR-06
    SYSTEM                                  5 25-APR-06
    OUTLN                                  11 25-APR-06
    SQL> create view v_tt as select username, user_id, created from tt@lk65 order by 2;
    View created.
    SQL> select * from v_tt;
    USERNAME                          USER_ID CREATED
    SYS                                     0 25-APR-06
    SYSTEM                                  5 25-APR-06
    OUTLN                                  11 25-APR-06
    SQL> create sequence seq_pk_tt_user_id
      2  minvalue 1000 maxvalue 99999
      3  increment by 1;
    Sequence created.
    SQL> CREATE OR REPLACE PROCEDURE prc_insert_tt(old_tt v_tt%ROWTYPE, new_tt v_tt%ROWTYPE) IS
      2  new_tt_user_id NUMBER;
      3  BEGIN
      4  SELECT seq_pk_tt_user_id.NEXTVAL INTO new_tt_user_id FROM dual;
      5  INSERT INTO tt
      6  (username, user_id, created)
      7  VALUES
      8  (new_tt.username, new_tt_user_id, new_tt.created);
      9  END prc_insert_tt;
    10  /
    Warning: Procedure created with compilation errors.
    SQL> show error
    Errors for PROCEDURE PRC_INSERT_TT:
    LINE/COL ERROR
    5/1      PL/SQL: SQL Statement ignored
    5/13     PL/SQL: ORA-00942: table or view does not exist
    SQL> edit
    Wrote file afiedt.buf
      1  CREATE OR REPLACE PROCEDURE prc_insert_tt(old_tt v_tt%ROWTYPE, new_tt v_tt%ROWTYPE) IS
      2  new_tt_user_id NUMBER;
      3  BEGIN
      4  SELECT seq_pk_tt_user_id.NEXTVAL INTO new_tt_user_id FROM dual;
      5  INSERT INTO tt@lk65
      6  (username, user_id, created)
      7  VALUES
      8  (new_tt.username, new_tt_user_id, new_tt.created);
      9* END prc_insert_tt;
    SQL> /
    Procedure created.Rgds.

Maybe you are looking for