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
Similar Messages
-
Instead Of Trigger And multiple Updable fields
Hi all,
I have an application based on a view (Customers,Products,..) above which an INSTEAD OF TRIGGER handles the updates done by end users.
A field,Updated_Date stores the date when the tuple was last modified.To better capture information and enhance the updates processes,
I want to store the exact date when a given field is modified.Only that field not the whole tuple.
Solution
Instead of 1 field,updated_date, i'd rather create 1 update_date_x for each column that might likely be modified.
I.e: updated_date_phone,updated_date_fax,...
Question
Is it possible to combine all those fields within a single Trigger firing with respect to the field being altered ?
Rather than creating a trigger for each updatable column.
Thks for any advise/point to a useful doc.
LamineCheck if the following helps.
http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96590/adg13trg.htm#376
From above link
Detecting the DML Operation That Fired a Trigger (INSERTING, UPDATING, and DELETING Predicates)
If more than one type of DML operation can fire a trigger (for example, ON INSERT OR DELETE OR UPDATE OF Emp_tab), the trigger body can use the conditional predicates INSERTING, DELETING, and UPDATING to check which type of statement fire the trigger.
Within the code of the trigger body, you can execute blocks of code depending on the kind of DML operation fired the trigger:
IF INSERTING THEN ... END IF;
IF UPDATING THEN ... END IF;
The first condition evaluates to TRUE only if the statement that fired the trigger is an INSERT statement; the second condition evaluates to TRUE only if the statement that fired the trigger is an UPDATE statement.
In an UPDATE trigger, a column name can be specified with an UPDATING conditional predicate to determine if the named column is being updated. For example, assume a trigger is defined as the following:
CREATE OR REPLACE TRIGGER ...
... UPDATE OF Sal, Comm ON Emp_tab ...
BEGIN
... IF UPDATING ('SAL') THEN ... END IF;
END;
The code in the THEN clause runs only if the triggering UPDATE statement updates the SAL column. This way, the trigger can minimize its overhead when the column of interest is not being changed. -
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,
HeinzHi 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. -
Insert order by records into a view with a instead of trigger
Hi all,
I have this DML query:
INSERT INTO table_view t (a,
b,
c,
d,
e)
SELECT a,
b,
c,
d,
e
FROM table_name
ORDER BY dtable_view is a view with an INSTEAD OF trigger and table_name is a table with my records to be inserted.
I need the ORDER BY clause because in my trigger i call a procedure who treat each record and insert into a table, used in the view. I need to garantee these order.
If i put an other SELECT statement outside, like this:
INSERT INTO table_view t (a,
b,
c,
d,
e)
SELECT a,
b,
c,
d,
e
FROM table_name
ORDER BY dIt works. But I can put these new SELECT because these query is created automatic by Oracle Data Integrator.
What I'm asking you is if there any solution to this problem without changing anything in the Oracle Data Integrator. Or, in other words, if there is any simple solution other than to add a new SELECT statement.
Thanks in advance,
Regards.Sorry... copy+paste error :)
INSERT INTO table_view t (a,
b,
c,
d,
e)
SELECT *
FROM ( SELECT a,
b,
c,
d,
e
FROM table_name
ORDER BY d)I need to insert him by a D column order, because my trigger needs to validate each record and insert him. I have some restrictions. For example, my records are:
2 1 2006 M
1 2 2007 M
1 3 2007 S 2007
1 2 2007 S 2007
2 1 2009 S
2 1 2009 S
I want to insert the 'M' records first and then the 'S' records because the 'S' records only makes sense in target table is exists 'M' records
Regards,
Filipe Almeida -
Instead-of Trigger Complication.
Hi folks,
Please look at the following table to have a clear picture,
I have 2 schemas namely, A and B.
I have 2 objects also X and Y. These are tables in schema A but these same tables (with same structures and data also ) are views in schema B.
In epitome, these X and Y views in schema B refer X and Y objects in schema A.
I have a trigger in schema A wherein before the updation of X, the trigger updates table Y. This is working fine.
Now, I have to write trigger T in schema B wherein before the updation of X, the trigger updates Y. But since both X and Y are views, obviously the trigger should be an INSTEAD-OF trigger and I want ot update the table Y in schema A (because Y in schema B is a view)
In the update statement (in the trigger in schema B), my business logic does not support hardcoding schema names like the following statement is prohibited.
update table A .Y set.....
instead i should write
update table Y set.....
and the above statement should consider the table Y in schema A because in schema B Y is a view that refers table Y in schema A.
How to achieve the desired result?
first of all, is there need to write the instead-of trigger in schema B?
If so how? How to reference the table in other schema without hardcoding its name?
Please do help me.
Your favour will be deeply appreciated.
Cheers, PCZ
schema object trigger
A X,Y (tables) T
B X,Y (Views) TWhat is purpose of creating views in schema B?. If it is for security reasons then the better option is to create synonym for tables in schema A. Schema A should grant privileges to schema B. Since both schemas are in the same database materialized views will not be beneficial.
-
Using Oracle 8.0.5 and
Forms 5.0.6.8.0
I created a view with an instead of trigger and I can insert rows using SQL.
When i create a form with a block based on the view and I try to update a row, the form returns the error "FRM-40602 cannot insert or update data in a view"
If I try to enter data in an item for insert, I get the error "FRM-40200 field is protected against update"
All the block and item properties seem to be set correctly for insert and update.
Why can't I insert or update?I think you want to post this question to the Developer 6.0 forum. This discussion forum is for JDeveloper, a different product.
Laura -
"instead of" trigger on a view with a condition
I'm trying to create an instead-of trigger on a view but I want it all such that:
1. It fires only for a certain condition.
2. When the condition isn't met, I want the normal DML on the view to continue as it normally would.
3. I want to avoid writing as much manual DML code as possible for long-term maintainability.
My first attempt is like this:
create or replace trigger PROPOSAL_PARTS_V_IRU
instead of update on proposal_parts_v
for each row
WHEN :old.PART_MASTER_ID <> :new.PART_MASTER_ID
BEGIN
do_stuff_for_part_master_change;
END;So when the OLD and NEW PART_MASTER_IDs have changed, I want special processing. Else, I want it to do whatever it normally does (let the view get updated and the database will manage the update of the underlying table).
When compiling that I get "ORA-25004: WHEN clause is not allowed in INSTEAD OF triggers".
OK I will accept that even though I want it to work.
So my next attempt could be:
create or replace trigger PROPOSAL_PARTS_V_IRU
instead of update on proposal_parts_v
for each row
BEGIN
IF :old.PART_MASTER_ID <> :new.PART_MASTER_ID THEN
do_stuff_for_part_master_change;
ELSE
UPDATE proposal_parts -- Manually update the underlying table with manually-written DML but I hate having to do this in case the view or table columns change.
SET...
WHERE...
END;So my question is...is there any syntax to do something like this?
create or replace trigger PROPOSAL_PARTS_V_IRU
instead of update on proposal_parts_v
for each row
BEGIN
IF :old.PART_MASTER_ID <> :new.PART_MASTER_ID THEN
do_stuff_for_part_master_change;
ELSE
update_row;
END;...where "update_row" is some sort of built-in command that tells oracle to continue with the current update as if the trigger never existed.
Back in the day I seem to remember that Oracle Forms had a trigger and syntax like this where you could intercept a DML and if under certain conditions it wasn't true, you could say "update_row" (or maybe it was "update_record?...whatever) and it meant "continue with update as if this instead-of trigger never existed".
Is anything available like that for the DB now? I know in older versions no, but we are now on 11g...anything new come out like this?
Otherwise I have to manually write an update statement and I'd rather not if I don't need to.
Thanks!riedelme wrote:
gti_matt wrote:
I'm trying to create an instead-of trigger on a view but I want it all such that:
1. It fires only for a certain condition.You can use IF Logic inside a trigger to do or not do anything. As long as it is a condition you can check you can code IF logic around it
2. When the condition isn't met, I want the normal DML on the view to continue as it normally would.You will have to code all of your logic in the INSTEAD of trigger. The whole purpose of the INSTEAD OF trigger is to execute INSTEAD OF performing DML on the view. There is no way to go back to the "normal DML" when the INSTEAD OF trigger exists.
You can put all of the logic you will need in the INSTEAD OF trigger and use IF conditions. Use IF logic to code both your special and "normal" processing.
3. I want to avoid writing as much manual DML code as possible for long-term maintainability.You will have to code the operative lines somewhere. Reusable functions and/or procedures in a package?Yep using an "IF" I knew about...no problem there.
But was just looking for a cheap and easy way to say (for the "else" condition) to revert to normal DML processing. Sounds like in a DB trigger there is no such syntax I guess.
This is an example from Oracle Forms, I was looking for a database equivalent of this(see http://sqltech.cl/doc/dev2000/help/fbhelp18.htm):
Built-in Subprograms for On-Event Triggers For most of the transactional On-event triggers, there is a corresponding built-in subprogram.
On-Event Trigger
Corresponding Built-in
On-Delete
DELETE_RECORD
On-Insert
INSERT_RECORD
On-Update
UPDATE_RECORD
When you call one of these built-in subprograms from its corresponding transactional trigger, Form Builder performs the default processing that it would have done normally at that point in the transaction.
For example, if you call the INSERT_RECORD procedure from an On-Insert trigger, Form Builder performs the default processing for inserting a record in the database during a commit operation.
When these built-ins are issued from within their corresponding transactional triggers, they are known as do-the-right-thing built-ins. That is, they do what Form Builder would normally have done at that point if no trigger had been present. Thus, an On-Insert trigger that calls the INSERT_RECORD procedure is functionally equivalent to not having an On-Insert trigger at all. Such a trigger is explicitly telling Form Builder to do what it would have done by default anyway.Note that the author calls them the "do-the-right-thing" built-ins. That's what I was looking for but on the DB side. Sounds like Oracle didn't come up with that (yet)? -
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. -
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
MarionHi 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 PMI 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..)
-
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,
HeinzDon'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? -
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
nullTHANKS 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 -
I have updated to ios6 and pushed merge instead of don't merge. I have a few apps same as my husbands and now my data is on his ipad, is there any way I can unmerge or anything he can do to stop me taking over his apps?
Did you try to set it up again as new device?
How to back up your data and set up as a new device -
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,
JeevanAs 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 can I retrieve the condition in an update or delete using instead of trigger
I have 2 tables, on which a view is created. To distinguish the tables within the view trigger, a column "source" had been added in the view creation. I want to be able to delete row(s) in table t1 or table t2 through the view, depending on a condition. The problem is that I don't know how I can get back the delete condition IN the INSTEAD of trigger :
CREATE TABLE t1(m NUMBER, n VARCHAR2(10), o date);
CREATE TABLE t2(a NUMBER, b VARCHAR2(10), c date);
-- The view is created based on the 2 tables.
CREATE OR REPLACE VIEW vt12 AS
SELECT 't1' source, m, n, o
FROM t1
UNION
SELECT 't2' source, a, b, c
FROM t2;
-- The trigger will fire whenever INSERT is performed on the tables through the view
create or replace trigger tvt12 instead of insert or delete on vt12
begin
if inserting then
if :new.source = 't1' then
insert into t1 values (:new.m, :new.n, :new.o);
else
-- will insert a default value of -1 for the fourth column "d"
insert into t2(a,b,c,d) values (:new.m, :new.n, :new.o, -1);
end if;
elsif deleting then
-- We don't know the condition for the deletion, so all rows from the
-- table from which the current row is coming will be deleted
if :old.source = 't1' then
delete t1;
else
delete t2;
end if;
end if;
end;
show error
insert into vt12 values ('t1',1,'1',sysdate);
insert into vt12 values ('t2',2,'2',sysdate+1);
insert into vt12 values ('t1',3,'3',sysdate+2);
insert into vt12 values ('t2',4,'4',sysdate+3);
insert into vt12 values ('t1',5,'5',sysdate+4);
insert into vt12 values ('t2',6,'6',sysdate+5);
commit;
select * from vt12;
select * from t1;
select * from t2;
delete vt12 where m = 1;
commit;
select * from vt12;
select * from t1;
select * from t2;
When I execute this script, the delete statement seems to recognize that the condition is affecting a row in table t1, and therefore deletes all rows from the table, as specified in the delete statement of the trigger... But, what I want to do is ONLY to delete the row affected by the original condition. So my question is to know how I can get back the original condition for the delete, and still use it in the trigger, that will be executed INSTEAD of the delete statement.. I checked in the doc, and everywhere an example of INSTEAD OF trigger can be found, but it's always and only using an INSTEAD OF INSERT trigger, which doesn't need a condition.
Can anyone help ?
nullI've never faced this case myself, but from the documentation it would seem that the INSTEAD OF DELETE is also a FOR EACH ROW trigger. Therefore, you don't really have to worry about the actual "where" clause of the original "delete" operation: Oracle has it all parsed for you, so you just need to redirect, in turn, each view record being deleted to the appropriate table.
In extenso: for your
delete vt12 where m = 1;
=> the INSTEAD OF trigger fires once for all records in vt12 where m=1, and I would guess that you trigger code should look like:
begin
delete from t1 where m = :old.m and n = :old.n and o = :old.o;
delete from t2 where a = :old.m and b = :old.n and c = :old.o;
end;
It's a bit of overkill compared to the "where" clause of the original "delete" statement, but it should do the job...
BTW, if by any luck you do have some primary key on tables t1 and t2 (say: columns o and c respectively), then obviously you can make the thing simpler:
begin
delete from t1 where o = :old.o;
delete from t2 where c = :old.o;
end;
HTH - Didier
Maybe you are looking for
-
Initiall SharePoint Server 2013 setup -- unable to manage new User Profile Service Application
During initial farm setup, creating an initial User Profile Service Application works fine. However, once it's created, I cannot 'manage' it through the Manage Service Applications page in central admin. I get a generic error (Sorry, something went
-
Error while creating a extractor based on Functional Module
Hi, I am building an extactor based on afunction module.I created a DS and created a structure in Se11.When i am trying to put the extract structure in the Tables tab of the function module it gives me an error saying Tables parameters are obselete a
-
Horizontal Lines while Capturing video in Premiere Elements 12
Problem: I have a Sony DCR-TRV80 where video is captured on Mini DV tape. It connects to my PC via FireWire. PC has i7 CPU, Win 7 64bit. 8gig ram, raid 0 hard disks, nvidia video card. Lots of hard disk space. When I capture video, as it is captured,
-
Transferring LP's to a computer (iMac G4)
Does anyone know how to do this? Are instructions available anywhere? I have a computer and a turntable and a long cord, but so far no luck. Mary McDermut
-
Invoice issue -transfer to FI dat
hii all, please resolve this issue with clarification is point-by-point....... "Invoice amount is completely correct, but if you look at the trip details in the body of invoice they do not match. On the service billing document the expense detail on