Constraint Checking Vs After Row Trigger
According to db concepts Chap 17 Trigger -> Trigger Execution, integrity checking is performed BEFORE the after row trigger executed. I guess this is not 100% true. AFAIK, we can create an AFTER ROW trigger on a child table which automatically insert new referenced row in the parent table. e.g.
CREATE TABLE child (
child_id int primary key,
parent_id int references parent,
CREATE TABLE parent (
parent_id int primary key,
CREATE OR REPLACE TRIGGER A
AFTER INSERT OR UPDATE on child
FOR EACH ROW
BEGIN
INSERT INTO parent values (:new.parent_id,...);
END;
If the constraint checking is done before the trigger, the referential integrity should have been violated when the child row is inserted.
So if the documentation is wrong, when will the constraint checking be carried out with respect to trigger execution.
There are plenty of things that are easier and/or safer to do in an AFTER ROW trigger, since can see exactly what the data in the row has been set to by any BEFORE ROW triggers and you can't change the data inadvertently. If your BEFORE ROW triggers are calling relatively complex procedures owned by various disparate groups of developers, it can be non-trivial to ensure that every groups changes are perfectly coordinated. AFTER ROW triggers are a heck of a lot easier to deal with here because you don't have to worry about another section of code changing the data you're using to make your decision.
I'm hard pressed to think of something that couldn't possibly be accomplished in a BEfORE ROW trigger, though I suspect there are at least a few oddball situations.
Justin
Distributed Database Consulting, Inc.
http://www.ddbcinc.com/askDDBC
Similar Messages
-
Can't able to use :NEW in after insert trigger
When i am trying to assign value to an element of the NEW pseudo record, its giving error like :new pseudo record can't be used in this type of trigger.
What exactly i've done is given below
create or replace triger tri_name
after insert
on tab_name
for each row
begin
if :new.x='123' then
:new.y:=null;
end if;
end tri_name;
Thanks & Regards
--DKarfrom oracle documentation...
Old and new values are available in both BEFORE and AFTER row triggers. A new column value can be assigned in a BEFORE row trigger, but not in an AFTER row trigger (because the triggering statement takes effect before an AFTER row trigger is fired). If a BEFORE row trigger changes the value of new.column, then an AFTER row trigger fired by the same statement sees the change assigned by the BEFORE row trigger.
for more details read the documentation -
In the Oracle Lite documentation, there is a section:
==========================================================
3.11.3.2 Defer Constraint Checking Until After All Transactions Are Applied
1. Drop all foreign key constraints and then recreate them as DEFERRABLE constraints.
2. Bind user-defined PL/SQL procedures to publications that contain tables with referential integrity constraints.
3. The PL/SQL procedure should set constraints to DEFERRED in the BeforeApply function and IMMEDIATE in the AfterApply function as in the following example featuring a table named SAMPLE3 and a constraint named address.14_fk:
==========================================================
For step 1, I am assuming this is on the base table that the publication references, since it is the one throwing the FK constraint violations at me.
For step 2 however, are these procedures to be bound to the base tables as well, or somewhere else related to where the publication items are stored?
Thanks,
AllenIn this case, the data model that I have to work with causes this situation
TABLE A has 2 FK constraints to TABLE B
TABLE B has 1 FK constraint to TABLE A
In Oracle Lite, I:
1-create a record in TABLE A where both of the columns with FK constraints are null
2-create a record in TABLE B which refers to the original in TABLE A
3-create a second record in TABLE B which also refers to the record in TABLE A
4-update the record in TABLE A to refer to the 2 records in TABLE B
When these changes reach the mobile server, they are placed in the error queue, because steps 1 and 4 are being combined and performed as one single insert. Since the records from step 2 and 3 don't exist yet, there is an FK violation.
Is there a way to prevent the synchronization process from 'opitimizing' the transaction and combining steps 1 and 4? Everything works fine if I follow steps 1-4, but when 1 and 4 are combined it all falls apart.
Thanks,
Allen -
Hi All,
Can I have an after insert trigger on a table wherein the execution is also on the same table?
It's like 10 columns in the table A.
During a new row insertion, except one specific column(say 'J'), remaining all getting data.
Now 'after insert', need to update the data of the column J based on one inserted value for column say ID.
Code goes like below:
CREATE OR REPLACE TRIGGER UPDATE_J
AFTER INSERT ON A REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
begin
if :new.ID = 'N%' then
:new.J:= 'N';
else
:new.J:= 'M';
end if;
end;
Below is the error when I tried to execute that.
ORA-04091: table string.string is mutating, trigger/function may not see it
Cause: A trigger (or a user defined plsql function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it.
Action: Rewrite the trigger (or function) so it does not read that table.
Any idea to resolve?
Regards,
Seetharaman.Hi,
The docs say
Restrictions on AFTER
An AFTER row trigger or AFTER row section of a compound trigger can only read but not write into the :OLD or :NEW fields. When faced with problems like this, it is always a good thing to consult the documentation.
Regards
Peter -
After Update Trigger executes twice when single row is uptd thro proc
We have the below trigger in our db. When a single record is updated using a procedure the trigger is executed twice and it inserts two records in other table.
But when i issue an update statement using any sql client tool it is executing only once and inserts only one record in other table.
Can any one please help me to find the reason?
Trigger:*
create or replace TRIGGER CX_HEADER_ESCL_T1 AFTER UPDATE OF STATUS ON CX_HEADER
FOR EACH ROW
DECLARE
"b1-CTRIYJ" boolean := FALSE;
BEGIN
IF UPDATING('STATUS') AND(:NEW.status = 'SUCCESS') THEN
"b1-CTRIYJ" := TRUE;
END IF;
IF "b1-CTRIYJ" = TRUE THEN
INSERT
INTO siebel.s_escl_req(req_id, created, bt_row_id, rule_id, tbl_name, created_by, group_id)
VALUES('11111111', CURRENT_DATE, :NEW.row_id, '1-CTRIYJ', 'CX_HEADER', :NEW.last_upd_by, '1-2CU3');
"b1-CTRIYJ" := FALSE;
END IF;
END;
Procedure:
CREATE OR REPLACE
PROCEDURE CLOSE_BATCH
(ChildRecordCount IN NUMBER, HeaderId IN VARCHAR2, CompletionStatus OUT VARCHAR2) AS
CafeChildCount NUMBER;
BEGIN
select count(*) into CafeChildCount from SIEBEL.CX_CHILD where HEADER_ID=HeaderId;
IF ChildRecordCount = CafeChildCount THEN
update SIEBEL.CX_HEADER set STATUS ='SUCCESS', MODIFICATION_NUM = MODIFICATION_NUM+1 where HEADER_ID=HeaderId;
CompletionStatus := 'SUCCESS';
ELSE
update SIEBEL.CX_CHILD set STATUS='FAILED' where HEADER_ID=HeaderId;
update SIEBEL.CX_HEADER set STATUS='FAILED' where HEADER_ID=HeaderId;
CompletionStatus := 'FAILED';
END IF;
commit;
/*CompletionStatus := 'SUCCESS';*/
EXCEPTION
WHEN OTHERS THEN
CompletionStatus := SQLCODE;
rollback;
END;Your problem seems not be related to the trigger restart issue I have already mentioned because you are using a AFTER UPDATE trigger and not a BEFORE UPDATE trigger:
>
BEFORE Triggers Fired Multiple Times
If an UPDATE or DELETE statement detects a conflict with a concurrent UPDATE, then Oracle Database performs a transparent ROLLBACK to SAVEPOINT and restarts the update. This can occur many times before the statement completes successfully. Each time the statement is restarted, the BEFORE statement trigger is fired again. The rollback to savepoint does not undo changes to any package variables referenced in the trigger. Your package should include a counter variable to detect this situation.
>
If you are sure that you update a single row and that your trigger fires twice and if you can easiily reproduce the issue, I recommend that you contact Oracle Support and create a Service Request for your issue that could be an Oracle bug. -
Update by after insert trigger
I need to update each new inserted row of data by checking if there were same values in the table. So I tried the After Insert Trigger with the code below :
CREATE OR REPLACE TRIGGER approve_checker
after insert on TBL_BILL
for each row
declare
counter integer;
begin
SELECT COUNT() INTO counter FROM TBL_BILL WHERE issue_date=:NEW.issue_date AND wagon_no=:NEW.wagon_no ;*
IF( counter > 1)
THEN
UPDATE TBL_BILL SET approved = 2 WHERE id = :NEW.id;
END IF;
end approve_checker;
But errors accured :
ORA-04091: table RAIL.BILL is mutating, trigger/function may not see it
ORA-06512: at "RAIL.APPROVE_CHECKER", line 4
ORA-04088: error during execution of trigger 'RAIL.APPROVE_CHECKER'
Any help appreciated.You cannot SELECT from the table on which the row-level trigger is defined, nor can you UPDATE a table on which the row-level trigger is defined. If you are inserting multiple rows in a single INSERT statement, Oracle can't be sure what rows to update and/or select.
Is there a reason that you wouldn't just create a unique constraint to enforce this condition?
Justin -
AFTER SERVERERROR trigger exceptions
AFTER SERVERERROR triggers fire after an Oracle error is raised, unless the error is one of the following:
ORA-00600 Oracle internal error (understandable)
ORA-01034 Oracle not available (understandable)
ORA-01403 No data found
ORA-01422 Exact fetch returns more than requested number of rows (too many rows)
ORA-01423 Error encountered while checking for extra rows in an exact fetch
ORA-04030 Out-of-process memory when trying to allocate N bytes
Anyone know why these errors are excluded?
GusMy guess would be that 1403 and 1422 are not really errors, but exception conditions that may or may nor be expected. Any select that returns no rows raise 1403, and it is up to the client to determine whether or not that is an error. I would assume similar reasoning for 1422.
For the 4030 error, I would assume that if there is no process memory, then the trigger could not fire because it would require more process memory to fire the trigger.
The oerr utility reports this for 1423:
01423, 00000, "error encountered while checking for extra rows in exact fetch"
// *Cause:
// *Action: See the following error and take appropriate action.I would strongly suspect that the following error would likely be one of 600, 1034, 3113, or one of the similar something bad happend but I don't know what errors.
HTH
John -
After update trigger with condition
Dear members,
I have a table with multiple columns on each update on these columns I have to update another table columns.
for one column the following trigger is working fine, but there are about more than 10 columns which I have to check for.
I want to create only one after update trigger on this table and check which column is updated and update the same column in 2nd table.
here is the trigger:
CREATE OR REPLACE TRIGGER ABC_RATE_UPD
AFTER UPDATE
OF RATE
ON ABC_PCD
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
DECLARE
BEGIN
UPDATE RM_TRAN_IN
SET RATE = :NEW.RATE
WHERE RM_PCD_ID = :NEW.RM_PCD_ID;
EXCEPTION
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
RAISE;
END ABC_RATE_UPD; here is my if condition, (edited)
if :NEW.RATE != :OLD.RATE then
UPDATE ABC_TRAN_IN
SET RATE = :NEW.RATE
WHERE ABC_PCD_ID = :NEW.ABC_PCD_ID;
ELSIF :NEW.PACK_UNIT_ID != :OLD.PACK_UNIT_ID then
UPDATE ABC_TRAN_IN
SET PACK_UNIT_ID = :NEW.PACK_UNIT_ID
WHERE ABC_PCD_ID = :NEW.ABC_PCD_ID;
END IF;
Its working good, is this a good approach, to the solution?
regards:
Edited by: user2040934 on Dec 29, 2012 3:22 PMIn your trigger if you update more than one column at a time will it update all the updated columns in the other table properly?
Can't you code something like this
CREATE OR REPLACE TRIGGER ABC_RATE_UPD
AFTER UPDATE
OF col1,col2 , col3
ON ABC_PCD
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
DECLARE
BEGIN
if updating ('col1') then
UPDATE RM_TRAN_IN
SET col1 = :NEW.col1
WHERE :old.id = :NEW.id;
end if;
if updating ('col2') then
UPDATE RM_TRAN_IN
SET col2 = :NEW.col2
WHERE :old.id = :NEW.id;
end if;
if updating ('col3') then
UPDATE RM_TRAN_IN
SET col3 = :NEW.col3
WHERE :old.id = :NEW.id;
end if;
EXCEPTION
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
RAISE;
END ABC_RATE_UPD; -
Can a constraint check two different tables for the existence of a parent item?
My database has a table Message, and a table MessageReply.
Each MessageReply has a ParentID and a MessageReplyType (Message, or Reply).
When the MessageReplyType is a message, I would like to ensure the MessageReply.ParentID (MessageID) exists in the Message table.
And when the MessageReplyType is a reply, I need to ensure the MessageReply.ParentID (MessageID) exists in the MessageReply table.
I am doing this through client code, but I would like the database to enforce this to protect the database from well intentioned programmers like me.
Can it be done?
Thank youThere is a problem with your function and the whole idea of using a check constraint and a function to simulate a foreign key constraint is problematic.
The problem with your function is when you do a statement like
Set @ReturnValue = (Select MessageID From MessageReply Where MessageID = @ParentID);
then if that row does not exist in MessageReply, @ReturnValue is set to NULL. Then you are returning that NULL from the function and using the check constraint to test whether or not that returned NULL is > 0. Comparing NULL to a value does
not give you TRUE and it does not give you FALSE, instead you get a logical value called UNKNOWN. Check constraints only reject a row if the resulting value is FALSE. It allows the Insert or Update if the logical value is either TRUE or UNKNOWN.
So even if the parent row does not exist, that check constraint will allow the new row to be inserted.
Second, using a function and check constraint to simulate a foreign key constraint always has a problem. If you go with that (and you have written the function and constraint correctly) and you attempt to insert a row with a bad ParentID so that the
ParentID does not exist in the appropriate table, you will get a check constraint error and the insert will be rejected. That is good. However, suppose you successfully insert a row in MessageReply. For example you insert a row in Message with
MessageID = 1 and then insert a row in MessageReply with ParentID = 1 and ReplyType = 1. That will work fine as it should. But now suppose someone deletes the row in Message with MessageID = 1. That delete won't fire the check constraint.
So it will allow the delete of the row in Message and now you have a row in MessageReply which doesn't have a parent.
If you want a method that will work completely, you could do that by 1) doing all of your updates to those tables thought stored procedure(s) that check the data to be sure it is valid before inserting/updating/deleting, or 2) writing trigger(s) on both
Message and MessageReply to make sure that any changes are valid, or 3) add computed columns to the MessageReply table so that you can write foreign key constraints.
I would go with method 3. That would look something like changing your MessageReply table to look something like
Create Table Message(MessageID int Primary Key
-- other columns as needed
Create Table MessageReply(MessageID int Primary Key
,ParentID int Not Null
,MessageReplyType int Not Null Check (MessageReplyType In (1,2))
,ParentMessageID As Case When MessageReplyType = 1 Then ParentID Else Null End Persisted
,ParentMessageReplyID As Case When MessageReplyType = 2 Then ParentID Else Null End Persisted
-- other columns as needed
Alter Table MessageReply
add constraint chk_MessageParentExists Foreign Key(ParentMessageID) References Message;
Alter Table MessageReply
add constraint chk_MessageReplyParentExists Foreign Key(ParentMessageReplyID) References MessageReply;
Tom -
How to apply the constraint ONLY to new rows
Hi, Gurus:
I have one question as follows:
We need to migrate a legacy system to a new production server. I am required to add two columns to every table in order to record who updates the row most recently through triggers, and I should apply not null constraint to the columns . However, since legacy system already has data for every table, and old data does not have value for the 2 new columns. If we apply the constraint, all of existing rows will raise exception. I wonder if there is possibility to apply the constraint ONLY to new rows to come in future.
Thanks.
SamWe need to migrate a legacy system to a new production server. I am required to add two columns to every table in order to record who updates the row most recently through triggers, and I should apply not null constraint to the columns .
The best suggestion I can give you is that you make sure management documents the name of the person that came up with that hair-brained requirement so they can be sufficiently punished in the future for the tremendous waste of human and database resources they caused for which they got virtually NOTHING in return.
I have seen many systems over the past 25+years that have added columns such as those: CREATED_DATE, CREATED_BY, MODIFIED_DATE, MODIFIED_BY.
I have yet to see even ONE system where that information is actually useful for any real purpose. Many systems have application/schema users and those users can modify the data. Also, any DBA can modify the data and many of them can connect as the schema owner to do that.
Many tables also get updated by other applications or bulk load processes and those processes use generic connections that can NOT be tied back to any particular system.
The net result is that those columns will be populated by user names that are utterly useless for any auditing purposes.
If a user is allowed to modify a table they are allowed to modify a table. If you want to track that you should implement a proper security strategy using Oracle's AUDIT functionality.
Cluttering up ALL, or even many, of your tables with such columns is a TERRIBLE idea. Worse is adding triggers that server no other purpose but capture useless infomation but, because they are PL/SQL cause performance impacts just aggravates the total impact.
It is certainly appropriate to be concerned about the security and auditability of your important data. But adding columns and triggers such as those proposed is NOT the proper solution to achieve that security.
Before your organization makes such an idiotic decision you should propose that the same steps be taken before adding that functionality that you should take before the addition of ANY MAJOR structural or application changes:
1. document the actual requirement
2. document and justify the business reasons for that requirement
3. perform testing that shows the impact of that requirement on the production system
4. determine the resource cost (people, storage, etc) of implementing that requirement
5. demonstrate how that information will actually be used EFFECTIVELY for some business purpose
As regards items #1 and #2 above the requirement should be stated in terms of the PROBLEM to be solved, not some preconceived notion of the solution that should be used.
Your org should also talk to other orgs or other depts in your same org that have used your proposed solution and find out how useful it has been for them. If you do this research you will likely find that it hasn't met their needs at all.
And in your own org there are likely some applications with tables that already have such columns. Has anyone there EVER used those columns and found them invaluable for identifying and resolving any actual problem?
If you can't use them and their data for some important process why add them to begin with?
IMHO it is a total waste of time and resources to add such columns to ALL of your tables. Any such approach to auditing or security should, at most, be limited to those tables with key data that needs to be protected and only then when you cannot implement the proper 'best practices' auditing.
A migration is difficult enough without adding useless additional requirements like those. You have FAR more important things you can do with the resources you have available:
1. Capture ALL DDL for the existing system into a version control system
2. Train your developers on using the version control system
3. Determining the proper configuration of the new server and system. It is almost a CERTAINTY that settings will get changed and performance will suffer even though you don't think you have changed anything at all.
4. Validating that the data has been migrated successfully. That can involve extensive querying and comparison to make sure data has not been altered during the migration. The process of validating a SINGLE TABLE is more difficult if the table structures are not the same. And they won't be if you add two columns to every table; every single query you do will have to specify the columns by name in order to EXCLUDE your two new columns.
5. Validating the performance of the app on the new system. There WILL BE problems where things don't work like they used to. You need to find those problems and fix them
6. Capturing the proper statistics after the data has been migrated and all of the indexes have been rebuilt.
7. Capturing the new execution plans to use a a baseline for when things go wrong in the future.
If it is worth doing it is worth doing right. -
Use of "DBA_OBJECTS" in "AFTER CREATE" Trigger
Hi,
We would like to store some extra information about our objects we have in the database. To do so we tought of the idea of creating a 'documenting' table containing an object_id that references to the object_id from the view dba_views.
Now we want to automatically create a new record in our documenting table when a new object is created, in the first stage this should only contain the object_id
To accomplish this we are using an 'AFTER CREATE' trigger, but when this trigger fires and the code searches for the new object_id in dba_objects, it does not return any records and generates an error. Likely because when the trigger is executed, the view is not yet updated?
create or replace
TRIGGER TRG_TEST
AFTER CREATE ON SCOTT.SCHEMA
DECLARE
tmp VARCHAR2(50);
BEGIN
dbms_output.put_line(ora_dict_obj_name);
select object_id
into tmp
from dba_objects
where object_name = ora_dict_obj_name;
dbms_output.put_line(tmp);
END;
Error report:
ORA-04088: Fout bij uitvoering van trigger 'SCOTT.TRG_TEST'.
ORA-01403: Geen gegevens gevonden.
ORA-06512: in regel 6
04088. 00000 - "error during execution of trigger '%s.%s'"
*Cause: A runtime error occurred during execution of a trigger.
*Action: Check the triggers which were involved in the operation.
It's in dutch, so I'll have a go at translating:
Error report:
ORA-04088: Exception while executing trigger 'SCOTT.TRG_TEST'.
ORA-01403: No data found
ORA-06512: in rule 6
04088. 00000 - "error during execution of trigger '%s.%s'"
*Cause: A runtime error occurred during execution of a trigger.
*Action: Check the triggers which were involved in the operation.
Does anyone have an idea of how I can accomplish what I'm trying to do here.. Or maybe something I'm doing wrong?
Thanks in advance!
DavyWhat is "ora_dict_obj_name" defined as?
Another option might be to setup a DBMS_SCHEDULER job to run the following insert
firstly though, create the following table ;
create document_table as (select * from dba_objects where rownum < 1)and then setup a DBMS_SCHEDULER job to run the following:
begin
insert into document_table
(select dbo.*
from dba_objects dbo
,document_Table dtb
where dbo.Object_ID = dtb.Object_ID(+)
and dtb.Object_ID is null);
commit;
exception
when others then
rollback;
-- log a message somewhere with the error, i.e. SQLERRM
end;
/Note, I specified all columns, but you'll probably specify explicitly which column you require, in which case the CREATE table would change as well.
Then you won't have a need for any trigger, and can better manage when you want your documentation to be updated.
Another option might be to use COMMENT, which can be used on tables, views, materialized views, but won't cover all objects
to the extent you might want.
SQL> desc emp2
Name
EMPNO
JOB
START_DATE
SAL
DEPT
END_DATE
SQL> comment on column emp2.sal is 'Existing Salary of employee as paid at most recent month end'; -
Hello all,
I have a question about after insert trigger. Will be new row inserted and commited if after insert trigger returns error? Thank you.
regards,
MihaWhat is the error that u r facing?
there could multiple reasons for that. Basically, u can't put commit in the trigger (unless it is an autonomous transaction). Share the pseudo-code of u r triiger, so that , problem can be identified.
Cheers,
Ram Kanala -
:NEW cannot be used in After Delete Trigger ?
Hi,
Is there any way to get the :NW.value in the After delete trigger for each row. My requirement is audit log of the end user DML operations along with user Name (HERE THE USER IS NOT THE ORACLE USER, BECAUSE OF THE LARGE NUMBER OF END USERS WE ARE MAINTAINING ONE TABLE TO CREATE USER NAME & PASSWORD, WHEN THE USER LOGIN TO ORACLE FORM SCREEN, ASSIGN THE USER NAME TO GLOBAL VARIABLE) & Action Date.
Here is my code for trigger - It is working fine with INSER & UPDATE but for DELETE User is NULL
CREATE OR REPLACE TRIGGER Tgr_stud_det
AFTER INSERT OR UPDATE OR DELETE ON student_details
FOR EACH ROW
DECLARE
BEGIN
IF Inserting THEN
-------------INSERT VALUE---------------
INSERT INTO Log_student_details
(Seq,
App_User,
Action,
Action_Date,
stud_name,
stud_age,
stud_sex)
VALUES
(stud_sequence.NEXTVAL,
:NEW.App_User,
'INSERT',
SYSDATE,
:NEW.stud_name,
:NEW.stud_age,
:NEW.stud_sex);
-------------DELETE VALUE---------------
ELSIF Deleting THEN
INSERT INTO Log_student_details
(Seq,
App_User,
Action,
Action_Date,
Comment_Up,
stud_name,
stud_age,
stud_sex)
VALUES
(stud_sequence.NEXTVAL,
:OLD.App_User,
'DELETE',
SYSDATE,
NULL,
:OLD.stud_name,
:OLD.stud_age,
:OLD.stud_sex);
ELSIF Updating THEN
-------------UPDATE VALUE---------------
INSERT INTO Log_student_details
(Seq,
App_User,
Action,
Action_Date,
Comment_Up,
stud_name,
stud_age,
stud_sex)
VALUES
(stud_sequence.NEXTVAL,
:NEW.App_User,
'UPDATE',
SYSDATE,
'NEW VALUE',
:NEW.stud_name,
:NEW.stud_age,
:NEW.stud_sex);
INSERT INTO Log_student_details
(Seq,
App_User,
Action,
Action_Date,
Comment_Up,
stud_name,
stud_age,
stud_sex)
VALUES
(stud_sequence.CURRVAL,
:NEW.App_User,
'UPDATE',
SYSDATE,
'OLD VALUE',
:OLD.stud_name,
:OLD.stud_age,
:OLD.stud_sex);
END IF;
EXCEPTION
WHEN OTHERS THEN
NULL;
END Tgr_stud_det;
Thanks in advance.Rizly,
As i mentioned in the above post, you should remove the references of :old and :new when you are trying to use the global variables. These values are only significant when you the talk about the record in the table.
For the scenario, you explained, your trigger would insert two records....The trigger would be fired twice.. once during the insert and once during the delete. The audit table will have two records indicating both the actions..
Take a look at this example below...I am artificially manufacturing a user id in the package test_pkg and using that in the insert trigger. As i explained above, you dont need the :old and :new references because the user id is not a column in the table . hence the :old and :new references have no relevance.
Also note that, for the delete, I use the :old value and for the insert, I use the :new value.
for update, I assume you want to store the old record and hence used :old (you can of course use :new too..technically.).
I don't have access to a forms environement, but the user id logic should be similar to what I described below.
sql> create table t(
2 id number,
3 name varchar2(20)
4 );
Table created.
sql> create table t_audit
2 ( id number,
3 name varchar2(20),
4 action varchar2(20),
5 user_id varchar2(20)
6 );
Table created.
sql> create or replace package test_pkg as
2 function get_user_id return varchar2;
3 end test_pkg;
4 /
Package created.
sql> create or replace package body test_pkg as
2 function get_user_id return varchar2 is
3 begin
4 return 'USER' || to_char(sysdate,'HH24:MI');
5 end get_user_id;
6 end test_pkg;
7 /
Package body created.
1 create or replace trigger trg_biud_t
2 before insert or update or delete on t
3 for each row
4 begin
5 if INSERTING then
6 insert into t_audit values (:new.id, :new.name, 'INSERT',test_pkg.get_user_i
7 elsif UPDATING then
8 insert into t_audit values (:old.id, :old.name, 'UPDATE',test_pkg.get_user_i
9 elsif DELETING then
10 insert into t_audit values (:old.id, :old.name, 'DELETE',test_pkg.get_user_i
11 end if;
12* end;
sql> /
Trigger created.
sql> select * from t;
no rows selected
sql> select * from t_audit;
no rows selected
sql> insert into t values (100, 'Rajesh');
1 row created.
sql> insert into t values (200,'Kumar');
1 row created.
sql> delete from t where id = 200;
1 row deleted.
sql> commit;
Commit complete.
sql> select * from t
2 /
ID NAME
100 Rajesh
sql> select * from t_audit;
ID NAME ACTION USER_ID
100 Rajesh INSERT USER15:36
200 Kumar INSERT USER15:36
200 Kumar DELETE USER15:37 -
InfoPath form load rule is not checking all the rows in form library
Hi,
Requirement:
We have a form library named "HR Annual Review". In the InfoPath form we have two buttons "Save" and "Submit". User is allowed to Save multiple times and only once using Submit button. The file name of form library "HR
Annual Review" will be stored in the format “<username>+<mm>+<dd>+<yy>.xml”. Say for example, an user named Mike Walt submitted a form then the file name will be as “MikeWalt012314.xml”. If the same user (Mike Walt)
submits the form and tries to open the form for subsequent edit, then we need to show a view which has an error info saying “The Appraisal is already submitted for the current appraisal cycle”.
Solution we tried:
To achieve the above requirement, we tried using InfoPath Form Load and add a rule to check whether the combination of current user name and the year already exists in the filename column of the form library. But the rule we applied is not checking all the
rows in the form library. The rule is always checking the first row of the form library.
What we need:
We need the validation using InfoPath rule or some other way/solution to check whether the combination of current login username and current year file already exists in the form library.
Thanks in advance.
Srivignesh JHi Srivignesh,
Submit button Uses the Main Data connection to submit the data to the list. This is what you are using and naming the file in the format. You can create secondary data submit that will update the exiting item in the list. With this, you don't have to create
any rules to check all the rows which is also not possible in OOB InfoPath.
Once you have the two data connection, hide the toolbar from the form and display these two on the button. For The Submit button, apply the rule to hide the button if created by is not empty. For Save button, apply the rule to hide the button if Created
By is empty. This way, when a new form is created, you will see the Submit button, and when the user have to update the form, they will see Save button. Hope it help.s
Regards, Kapil ***Please mark answer as Helpful or Answered after consideration*** -
Calling of Stored Procedure in After Insert Trigger
Can I call a Stored Procedure in After Insert Trigger ?
Please send a sample code (good example) of After Insert Trigger.
Thanks.Kishore,
I have two table WLCS_ORDER, WLCS_ORDER_LINE
WLCS_ORDER - It holds order header information like
ORDER_ID
CUSTOMER_ID
TRANSACTION_ID
STATUS
ORDER_DATE
SHIPPING_METHOD
SHIPPING_AMOUNT
SHIPPING_CURRENCY
PRICE_AMOUNT
PRICE_CURRENCY
SHIPPING_GEOCODE
SHIPPING_STREET1
SHIPPING_STREET2
SHIPPING_CITY
SHIPPING_STATE
SHIPPING_COUNTRY
SHIPPING_POBOX
SHIPPING_COUNTY
SHIPPING_POSTAL_CODE
SHIPPING_POSTAL_CODE_TYPE
SPECIAL_INSTRUCTIONS
SPLITTING_PREFERENCE
ORDER_SUBTOTAL
WLCS_ORDER_LINE - It holds all order lines information like
ORDER_LINE_ID
QUANTITY
PRODUCT_ID
TAX_AMOUNT
TAX_CURRENCY
SHIPPING_AMOUNT
SHIPPING_CURRENCY
UNIT_PRICE_AMOUNT
UNIT_PRICE_CURRENCY
MSRP_AMOUNT
MSRP_CURRENCY
DESCRIPTION
ORDER_ID
TOTAL_LINE_AMOUNT
Relation between WLCS_ORDER, WLCS_ORDER_LINE is one to many.
For each WLCS_ORDER row, one or more order lines will insert into WLCS_ORDER_LINE table.
For each new row in WLCS_ORDER table, I have to update the following columns in both the tables with my maths.
WLCS_ORDER
shipping_amount
price_amount
order_subtotal
WLCS_ORDER_LINE
shipping_amount
I thought I can do this in after insert trigger, But if it is not possible, Please give the best way to fulfill this requirement.
I appreciate your help.
Have a great day.
Srinivas
Maybe you are looking for
-
My Adobe Bridge CS6 default open program has changed into "Window Live Photo Gallery" after uninstalled previous version of Bridge CS5. I uninstalled with remove all prefrenses. How can I get My Bridge CS6 default open program back to Photoshop CS6 ?
-
Syntax Error in Web UI component post upgrade
Hi Experts, We have a enhanced component in IC agent which is giving syntax error post upgrade from 7.0 to EHP2. It seems some attributes have been removed/altered in the new super class. In this case do we need to delete the component enhancement an
-
Nouveau graphical tearing, dual-head setup
I currently experience tearing while using the Nouveau drivers for my NVidia card. I experienced the same (or a similar) tearing issue while using the proprietary drivers, which, along with the inherent incompatibility with most of the linux graphics
-
Trying to find a new Graphics card for G4 Quicksilver Dual 1 ghtz
Hello All, I am looking to upgrade my video card for gaming purposes. I have been doing research and thought I had found a card I could use. Then I researched more, and confused myself. There comes a point when one must ask So I have the Geforce 4 MX
-
[SOLVED] BSPWM dzen2 panel not displaying workspaces.
I've been trying for a while to get the bar/dzen2 panel working in bspwm and everything works except for the desktop indicator. I've tried using the example configs along with a lot of other people's amazing configs. Nothing works. I got it working w