:old in trigger
How do I turn off bind variable substitution in Sql Developer 3.2 when I am creating a trigger that references old and new values using the colon-old format?
I can use set define off for sqlplus, but that doesn't work for the bind variable substitution issue in triggers
How do I turn off bind variable substitution in Sql Developer 3.2 when I am creating a trigger that references old and new values using the colon-old format?
I can use set define off for sqlplus, but that doesn't work for the bind variable substitution issue in triggers
You don't need to. Just use F5 to run the script. This works for me.
CREATE OR REPLACE TRIGGER TRIGGER1
BEFORE UPDATE ON DEPT
FOR EACH ROW
BEGIN
IF :old.dname = 'abc' THEN :new.dname := 'def'; END IF;
END;
Similar Messages
-
How to auto insert computed value when new data is created??
I'm new to APEX and was trying to solve this:
To make it simple: I have a table, square_table, with two fields: input_number and square_value.
All I want to do is when a user enters an input_number from 'the form and report template', the squared value is automatically computed and saved along with the new number to the square_table.
Would someone post a solution (as details as possible, pls :)? I have watched numerous tutorials and no luck.
Many Thanks,Poor design. You should not do this, even for strictly educational purposes. Stick to 3NF as much as possible, and only denormalize if a)you REALLY REALLY REALLY need to do it, AND b)your denormalized design survives peer review, AND c)you document VERY WELL the rationale behind such a design. Please read this - look for "Calculated Values".
Anyway. You could do this at least two ways:
1) Create a Page Process in your APEX application. Not a good idea, as other sources of INSERTs (sqplus, client/server apps) will not do the calculation unless coded to do so, and doing so would create multiple points of maintenance and documentation and testing, no to mention the added complexity of dealing with several potential development environments; or
2) Create a good old plain trigger.
If this was not a flawed design, I'd go for (2). It is basic SQL homework, well documented and simple to implement.
Regards,
Georger
user11288935 wrote:
I'm new to APEX and was trying to solve this:
To make it simple: I have a table, square_table, with two fields: input_number and square_value.
All I want to do is when a user enters an input_number from 'the form and report template', the squared value is automatically computed and saved along with the new number to the square_table.
Would someone post a solution (as details as possible, pls :)? I have watched numerous tutorials and no luck.
Many Thanks, -
Oracle 8i, Views and Triggers
Our application uses Views, which are essentially mirrors of the tables to perform all updates. A GRANT ALL to PUBLIC is given to the views. These updates fire Triggers on the Tables which has worked great until we attempted to run our application at a new client running 8i on Unix. I noticed the INSTEAD_OF option on triggers for 8i, but is it a definite requirement for 8i. I can't believe the old normal trigger code now fails on 8i (by disconnecting); or is it something else. Please advise.
nullWe asked our developers and here is the answer...and a follow up question.
The INSTEAD OF is a new option on triggers to work over views. This has absolutely no impact on existing triggers on tables. If you have a view defined over a table (or set of tables) and then perform any DML over the
view, in the regular case, the DML will translate to operations on the base tables and the appropriate triggers on the base table will fire.
With the new INSTEAD OF option since Oracle8.0, you can define a trigger over
a view itself, (particular if the view is complex enough that the system cannot handle inserts/updates/deletes on the view), and the trigger body will handle the DML by firing appropriate statements.
The problem you are seeing is probably something else.
What do you mean by "disconnecting"??
Are you getting some sort of error or something when using the old triggers??
-John
null -
Oracle 11g automatic archival // maintaining historic data
Hi Group,
We are planning to get Oracle 11g.
I want to know if Oracle 11g has the capability to do automatic archival?
My requirement is,
few of the tables in our application will have lot of records (data) and after some days/ months it might slog the performance cos of the table/db size, and also the old data will not be of much interest (but data cannot be purged/deleted until some years). Hence want to archive the old data (trigger conditions specified by the user) and will be needed to bring data back programatically whenever the user queries for the data belonging to that particular period(archived data).
Is there a feature available in Oracle to just specify the data to be archive and bring it back by giving a date/time input.Hi,
First, this looks like a job for Oracle partitioning.
What is your motive for archiving? Improved performance? Cheaper media?
I want to know if Oracle 11g has the capability to do automatic archival? Sure, but you would have to script it yourself. Many shops do time-based rollover archiving with partitioned tables:
http://www.dba-oracle.com/t_partitioned_tablespace_archiving.htm
it might slog the performance cos of the table/db sizeNo, not if you are properly indexed . . . However, table partitioning can speedup queries against large tables with "partition aware" SQL:
http://www.dba-oracle.com/t_partition_sql_index_ss_hint.htm
want to archive the old data (trigger conditions specified by the user) I would not use triggers, schedule a job instead:
http://www.dba-oracle.com/t_archiving_data_in_file_structures.htm
needed to bring data back Sorry, back from where? You are archving to disk, right? -
Releasenotes, bugfixes and enhancements
Hello,
I'm currently using Headstart version 6.5.1(.0). Can anyone send me the releasenotes, bugfixes or enhancements of all patches since then till version 6.5.3., or can anyone give me a good reason of upgrading.
All can be send to [email protected]
Thank you very much.Kristof,
The release notes of all patches.
Headstart Oracle Designer PATCH 6.5.3.0 FOR 9i
==============================================
This patch is ready for use with Designer 9i, Forms 9i and Reports 9i.
Also it addresses the following bugs and enhancement requests
(mostly the same that are addressed in PATCH 6.5.3.0 FOR 6i):
Bug No. Description
====== =======================================================================
2309129 - ERROR IN UNLD_RPTS.SQL SCRIPT
2309202 - NAVIGATOR FORMS DO NOT HAVE CG$STARTUP_MODE, CAUSES ERROR
2441289 - SAVE BUTTON STAYING DISABLED WHEN IT SHOULD BE ENABLED
2482013 - LOGGING INTO 9I SERVER AS SYS MUST BE DONE AS SYSDBA
2483045 - CHANGE OBJECT LIBRARY USAGE STANDARD IN HEADSTART USER GUIDE
2497339 - CALENDAR-LOV WITH TIME HAS EXTRA BUTTONS, PROBLEM WHEN NULL VALUE
2499198 - USE CALENDAR LOV, GET FRM-40102: "RECORD MUST BE ENTERED OR DELETED
FIRST"
2504387 - SET QMSOLB65.OLB DISPLAY ONLY ITEMS (CGSO$%_DO) TO ENABLED=YES
2520101 - OFGTEL65.PLL CANNOT BE COMPILED AGAINST HST65 TEMPLATE PACKAGE OWNER
2520119 - GENERATION OF HEADSTART DEMO FORM HSD0034F GIVES CDG-01117 INVALID
DISPLAY TYPE
2520191 - MESSAGE QMS-00125 DOES NOT EXIST IN QMS_MESSAGE_PROPERTIES, USED IN
QMSLIB65
2521218 - HEADSTART 6I DOES NOT COMPILE WITH FORMS 9I
2529003 - CAPI SHOULD NOT INCLUDE COLUMNS WITH COMPLETE = NO
2570562 - 'SAVE OLD DATA' NOT GENERATED WHEN CAPI UTILITY PARAM
'TAPI TRIGGERS' IS NO
2600939 - IF SUBTYPE ATTRIBUTE MAPPED TO MULTIPLE TABLES, UTILITY CAN TAKE THE
WRONG ONE
2605551 - STILL HAVE CODE FOR '_CASDEL' IN QMSLIB65.PLL QMS$FORMS_ERRORS
2635597 - HEADSTART 6.5 UTILITIES THAT CALL BLTEXT.DELETE_TAGGED_BLOCK FAIL
2635613 - CALL TO QMS$BLOCK.GO('<BLOCK NAME>') IN QMSLIB65 IS CASE SENSITIVE!!
2635789 - CAPI VALIDATED BUSINESS RULE AGAINST WRONG ROW FROM INTERNAL ROW
STACK
2651107 - CHANGE_CONNECTION DOES NOT UPDATE ENTIRE INFO ABOUT APPLICATION
Headstart Oracle Designer PATCH 6.5.3.0 FOR 6i
==============================================
This patch addresses the following bugs and enhancement requests:
Bug No. Description
======= ======================================================================
2309129 - ERROR IN UNLD_RPTS.SQL SCRIPT
2309202 - NAVIGATOR FORMS DO NOT HAVE CG$STARTUP_MODE, CAUSES ERROR
2482013 - LOGGING INTO 9I SERVER AS SYS MUST BE DONE AS SYSDBA
2441289 - SAVE BUTTON STAYING DISABLED WHEN IT SHOULD BE ENABLED
2483045 - CHANGE OBJECT LIBRARY USAGE STANDARD IN HEADSTART USER GUIDE
2497339 - CALENDAR-LOV WITH TIME HAS EXTRA BUTTONS, PROBLEM WHEN NULL VALUE
2499198 - USE CALENDAR LOV, GET FRM-40102: "RECORD MUST BE ENTERED OR DELETED
FIRST"
2504387 - SET QMSOLB65.OLB DISPLAY ONLY ITEMS (CGSO$%_DO) TO ENABLED=YES
2520101 - OFGTEL65.PLL CANNOT BE COMPILED AGAINST HST65 TEMPLATE PACKAGE
OWNER
2520119 - GENERATION OF HEADSTART DEMO FORM HSD0034F GIVES CDG-01117 INVALID
DISPLAY TYPE
2520191 - MESSAGE QMS-00125 DOES NOT EXIST IN QMS_MESSAGE_PROPERTIES,
USED IN QMSLIB65
2529003 - CAPI SHOULD NOT INCLUDE COLUMNS WITH COMPLETE = NO
2570562 - 'SAVE OLD DATA' NOT GENERATED WHEN CAPI UTILITY PARAM
'TAPI TRIGGERS' IS NO
2600939 - IF SUBTYPE ATTRIBUTE MAPPED TO MULTIPLE TABLES, UTILITY CAN TAKE
THE WRONG ONE
2605551 - STILL HAVE CODE FOR '_CASDEL' IN QMSLIB65.PLL QMS$FORMS_ERRORS
2635597 - HEADSTART 6.5 UTILITIES THAT CALL BLTEXT.DELETE_TAGGED_BLOCK FAIL
2635613 - CALL TO QMS$BLOCK.GO('<BLOCK NAME>') IN QMSLIB65 IS CASE SENSITIVE!
2635789 - CAPI VALIDATED BUSINESS RULE AGAINST WRONG ROW FROM INTERNAL
ROW STACK
2651107 - CHANGE_CONNECTION DOES NOT UPDATE ENTIRE INFO ABOUT APPLICATION
Headstart Oracle Designer 6i PATCH 6.5.2.3
CDM RuleFrame Performance Improvement
==========================================
The main purpose of this patch is to improve the performance of the
CDM RuleFrame engine when large transactions are involved.
The functionality of CDM RuleFrame is only slightly changed by this patch:
- The utility 'Create CAPI Custom Service' makes it possible to include
a CAPI Custom Service (i.e. your own package or function) in more
than one CAPI (see "BUG 2419371" below)
- The utility 'Create VAPI Definition' can now also create VAPI's for
subtypes (controlled by new utility parameter)
This patch addresses the following bugs and enhancement requests:
Bug No. Description
======= ======================================================================
2070417 - PERFORMANCE ENHANCEMENT SUGGESTION FOR DISABLING CDM
RULEFRAME IN BATCH MODE
2204246 - USE NATIVE DYNAMIC SQL FOR RULEFRAME RUNTIME
SOFTWARE
2220682 - IMPROVE RULEFRAME RUNTIME PERFORMANCE WITH NOCOPY
IN TRANSACTION MANAGEMENT
2220697 - RULEFRAME STACK: USE TEMPORARY DATABASE TABLES INSTEAD
OF PL/SQL TABLES
2220707 - STORE ROWS IN RULEFRAME ROW STACK ON AN INDEX CALCULATED BY
A HASH FUNCTION
2220908 - ELIMINATE ROW STACK FROM CAPI AND MAKE OLD ROW STACK SMALLER
2227746 - ENHANCE RULEFRAME PERFORMANCE BY MINIMIZING CAPI USE OF
FIND_ON_STACK
2249250 - WHEN CREATING CAPI FOR TABLE WITH MANY COLUMNS: ORA-06502 VALUE
ERROR
2259418 - IMPROVE RULEFRAME PERFORMANCE BY ENFORCING CERTAIN RULES
IMMEDIATELY
2394119 - RUNNING UTILITIES ERR.SQL GIVES ORA-20000: ORU-10028: LINE
LENGTH OVERFLOW
2394166 - WHEN BUSINESS RULE ALREADY EXISTS, UTILITY STILL TRIES TO
INSERT TRIGGER
2396132 - UTILITY JOURNALLING BUSINESS RULES ORA-01401: INSERTED VALUE
TOO LARGE IN BLTEXT
2419371 - POSSIBILTY TO USE SAME CUSTOM SERVICE IN MORE THAN ONE CAPI
PACKAGE
2441447 - REMOVE WORKAROUND FOR BUG 1347738 IN CAPI GENERATOR (HSU_CAPF)
2481957 - DEFAULT IN SPECIFICATION OF HSU_BRTR.RUN AT WRONG PARAMETER
2485658 - CDA-01305 COLUMN UID - WHEN SAVING RESULTS OF REFRESHING JOURNAL
TABLE UTILITY
Headstart Oracle Designer 6i PATCH 6.5.2.2
==========================================
This patch addresses the following bugs and enhancement requests:
Bug No. Description
======= ======================================================================
2283093 - RUNNING REPORTS USING DESTYPE=CACHE FROM REPORT LAUNCH FORM
2283122 - ERROR WHEN CLOSING WINDOW AFTER DUPLICATE RECORD KEY
2285936 - PROBLEMS WITH REPORT LAUNCH FORM IN 6.5.2.1 SUPPLEMENT OPTION
2303927 - QMS0012 REPORT LAUNCH FORM NO DEFAULT VALUES IN PARAMETERLIST AFTER
STARTUP
Headstart Oracle Designer 6i PATCH 6.5.2.1
==========================================
This patch addresses the following bugs and enhancement requests:
Bug No. Description
======= ======================================================================
1696475 - ONLINE HELP FOR REPORTS HAS STRANGE URL
1702857 - ORA-00600 WHEN TRYING TO RUN HEADSTART FORM USING FORMS DEBUGGER
1727439 - POOR PERFORMANCE IN UTILITY 'CREATE CAPI DEFINITION'
1727886 - ERRORS IN 'CREATE CAPI DEFINITION' UTILITY ARE IGNORED
1747626 - RULEFRAME 6I BUS. RULE VIOLATION ON DELETED RECORD GIVES ORA-01403
OR QMS-00100
1754565 - PROCEDURE QMS$ABOUT_THIS_APPLICATION IS MISSING IN YOUR APPLICATION
LIBRARY...
1754740 - SETUP PART OF USER GUIDE SHOULD MENTION ACCESS TO HEADSTART DATABASE
OBJECTS
1754906 - CREATE FIND WINDOW(S) - SAVING CHANGES FAILED WITH CDA-01151
1764270 - CHAPTER 17 REFERS TO SCRIPT HSU_USER.GRT, WHICH IS NOT AVAILABLE
1769077 - SERVER SIDE INSTALLER SAYS USER ALREADY INSTALLED WHEN MANUAL IMPORT
UTILITIES
1769234 - LONG BLOCK.ITEM NAME RESULTS IN QMS-00100: ORA-06502:
PL/SQL: NUMERIC/VALUE ERR.
1769321 - VALUE ERROR IN HTML ONLINE HELP GENERATOR WHEN ITEMS HAVE LONG HINT
TEXTS
1781424 - CDM RULEFRAME: TRIGGER ALREADY EXISTS ERROR EVEN IF TRIGGER IS IN
OTHER FOLDER
1781454 - CREATE DOMAINS FOR DISCRIMINATOR COLUMNS TRIES TO UPDATE DOMAIN IN
WRONG FOLDER
1802399 - WHEN VIEWING LOG: UNHANDLED EXCEPTION IN VIEW_LOG_MESSAGES:ORA-06502
1832171 - DROP THE PK ON QMS_TRANSACTIONS FOR PERFORMANCE REASONS
1869480 - REPORTS MODULES NOT SHOWN IN MULTI SELECT LIST OF UTIL SET
IMPLEMENTATION NAME
1877521 - ORA-06502 WHEN MAINTAIN BUSINESS RULE DESIGN DEFINITIONS FOR STATIC
DOMAINS
1885204 - BUSINESS RULE TRANSFORMER: TRIGGERING EVENT <X> IS INVALID.
IT HAS NO ENTITY...
1890011 - UNABLE TO GENERATE DEFAULT NULL PARAMETER IN CAPI CUSTOM SERVICE
1890029 - HSD 65 USER GUIDE MENTIONS STFFMB PREF.INST. OF PREF.
SET QMS65_LOV_MODULE
1890035 - SMALL OMISSIONS AND TYPOS IN HEADSTART 65 USER GUIDE
1891637 - REDIRECT HEADSTART REFERENCED OBJECTS: INVALID VALUE FOR OLD QMS
APP VERSION
1978916 - WITH OLD DB TRIGGER, SEE 'ORA-20998'IN FORM INSTEAD IF THE ACTUAL
MESSAGES
1979278 - F9 DOES NOT WORK FOR LIST OF VALUES ON MODAL DIALOG FORM
(ALSO UP/DOWN)
1985903 - APPLICATION CLOSES WHEN USING MULTI-SELECT FEATURES IN MODAL DIALOG
WINDOW
1987743 - ORA-06508: PL/SQL: COULD NOT FIND PROGRAM UNIT.. <TAPI PACKAGE>.INS
2093405 - WHEN INSTALLING HEADSTART IN A 9I DATABASE, CG$ERRORS WON'T COMPILE
ANYMORE
2101690 - ONLINE HELP FOR REPORTS (QMS0012F) DOESN'T WORK
2148764 - CG$ERRORS WON'T COMPILE ON 9I DATABASE
2148774 - ENABLED PROPERTY SET YES ON CGSO$..._DO OBJECTS IN OBJECT LIBRARY
2176331 - ERROR WITH ORDER BY CURRENT FIELD
2176348 - GET ERROR IF LAST REPORT PARAMETER IS TYPE DATE
2176364 - CREATE VIEW DEFINITION DOESN'T UPDATE WHERE CLAUSE OF DOMAIN KEY
CONSTRAINT
2185321 - COMPILATION ERRORS ORACLE 9I: DIFFERENCES PARAMETER DEFAULTS PACKAGE
SPEC/BODY
Regards,
Marcel -
Insert old missing data from one table to another(databaase trigger)
Hello,
i want to do two things
1)I want to insert old missing data from one table to another through a database trigger but it can't be executed that way i don't know what should i do in case of replacing old data in table_1 into table_2
2)what should i use :NEW. OR :OLD. instead.
3) what should i do if i have records exising between the two dates
i want to surpress the existing records.
the following code is what i have but no effect occured.
CREATE OR REPLACE TRIGGER ATTENDANCEE_FOLLOWS
AFTER INSERT ON ACCESSLOG
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
V_COUNT NUMBER(2);
V_TIME_OUT DATE;
V_DATE_IN DATE;
V_DATE_OUT DATE;
V_TIME_IN DATE;
V_ATT_FLAG VARCHAR2(3);
V_EMP_ID NUMBER(11);
CURSOR EMP_FOLLOWS IS
SELECT EMPLOYEEID , LOGDATE , LOGTIME , INOUT
FROM ACCESSLOG
WHERE LOGDATE
BETWEEN TO_DATE('18/12/2008','dd/mm/rrrr')
AND TO_DATE('19/12/2008','dd/mm/rrrr');
BEGIN
FOR EMP IN EMP_FOLLOWS LOOP
SELECT COUNT(*)
INTO V_COUNT
FROM EMP_ATTENDANCEE
WHERE EMP_ID = EMP.EMPLOYEEID
AND DATE_IN = EMP.LOGDATE
AND ATT_FLAG = 'I';
IF V_COUNT = 0 THEN
INSERT INTO EMP_ATTENDANCEE (EMP_ID, DATE_IN ,DATE_OUT
,TIME_IN ,TIME_OUT,ATT_FLAG)
VALUES (TO_NUMBER(TO_CHAR(:NEW.employeeid,99999)),
TO_DATE(:NEW.LOGDATE,'dd/mm/rrrr'), -- DATE_IN
NULL,
TO_DATE(:NEW.LOGTIME,'HH24:MI:SS'), -- TIME_IN
NULL ,'I');
ELSIF V_COUNT > 0 THEN
UPDATE EMP_ATTENDANCEE
SET DATE_OUT = TO_DATE(:NEW.LOGDATE,'dd/mm/rrrr'), -- DATE_OUT,
TIME_OUT = TO_DATE(:NEW.LOGTIME,'HH24:MI:SS'), -- TIME_OUT
ATT_FLAG = 'O'
WHERE EMP_ID = TO_NUMBER(TO_CHAR(:NEW.employeeid,99999))
AND DATE_IN <= (SELECT MAX (DATE_IN )
FROM EMP_ATTENDANCEE
WHERE EMP_ID = TO_NUMBER(TO_CHAR(:NEW.employeeid,99999))
AND DATE_OUT IS NULL
AND TIME_OUT IS NULL )
AND DATE_OUT IS NULL
AND TIME_OUT IS NULL ;
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN RAISE;
END ATTENDANCEE_FOLLOWS ;
Regards,
Abdetu..INSERT INTO SALES_MASTER
( NO
, Name
, PINCODE )
SELECT SALESMANNO
, SALESMANNAME
, PINCODE
FROM SALESMAN_MASTER;Regards,
Christian Balz -
Retrieving old column values from a after delete trigger dynamically
I have a single audit table for deletions
and the table structure has the following columns
1: table_name
2: column_name
3: column_value
I am writing a trigger on tables for which i want to have delete audits and i am dynamicaly
retrieving the column names but i am unable to retrieve the column value dynamically;
I tried to use the following statement but doesn't return the column value
sql_stmt:= 'select :1 from dual';
execute immediate sql_stmt into col_value using
':old.'| |v_col_name;
where v_col_name is the name of the column which i retrieve dynamically using the
dbms_sql.describe_columns procedure.
Is their any way if i can retrieve the old column values in the trigger dynamically if i already
have the column names in variables..
Thanks in advance.
nullI don't know if Kevin's tip Help Mr. Sameer, but it did help me gain access to pre-deleted row column values.
I did discover, however, that if the columns from the about-to-be-deleted row are used as inserts into another table, Oracle serves up a nasty-gram informing the user that values from the about-to-be-deleted table are unreliable.
I was able to circumvent this constraint by assigning the about-to-be-deleted column values to local PL/SQL varables, then perform the insert using the variable values.
-Bill McNamee
NHDOT
[email protected] -
Get OLD&NEW value of an UPDATED column selected dynamically in a Trigger
Hi All,
I am writting a trigger which take column name dynamically. And on the basis of that column it should give me old value as well as updated value of a column corresponding to a modified row.
OOO_SCHEDULE is my table name;
Note: This is only for test so I am writting only for update not for insert and delete.
create or replace trigger "OOO_SCHEDULE_AUDIT"
BEFORE
insert or update or delete on "OOO_SCHEDULE"
for each row
begin
DECLARE
v_username varchar2(30);
AUDIT_EMP_ID varchar2(30);
AUDIT_EMP_ID_NEW varchar2(30);
v_Column_name VARCHAR(30);
v_stmt1 VARCHAR(40);
v_stmt2 VARCHAR(40);
CURSOR C1 is
select COLUMN_NAME from user_tab_columns where table_name='OOO_SCHEDULE';
BEGIN
OPEN c1;
LOOP
FETCH c1 into v_Column_name;
EXIT WHEN c1%NOTFOUND;
v_stmt1:=('OLD.'||v_Column_name);
v_stmt2:=('NEW.'||v_Column_name);
AUDIT_EMP_ID:=v_stmt1;
AUDIT_EMP_ID_NEW:=v_stmt2;
INSERT INTO TEMPTEST VALUES(v_stmt1);
INSERT INTO TEMPTEST VALUES(AUDIT_EMP_ID);
END LOOP;
CLOSE c1;
END;
end;
Suppose OOO_EMP_NAME is the column name where user made the change.
If i do like this..
AUDIT_EMP_ID:=OLD.OOO_EMP_NAME;
AUDIT_EMP_ID_NEW:=NEW.OOO_EMP_NAME;
Then it is working fine because I have given column name statically. But I want the column name to be selected dynamically and I am able to do it through cursor. Also I am able to fetch all column names in v_Column_name variable one by one dyanamically for the cursor.
But by executing these statements
AUDIT_EMP_ID:=v_stmt1;
AUDIT_EMP_ID_NEW:=v_stmt2;
I am getting OLD.OOO_EMP_NAME and NEW.OOO_EMP_NAME rather then old and new values of the updated column.
Please help me identifying the problem, where I am doing the mistake? What is the correct way to execute these statements? So that I can get old and new values of the column (updated column).
I have tried it by passing in a procedure also but don't know how to execute this dynamic statement to get the old and new values.
Thanks,
Ishrat.In the given link, column name has been selected statically. But i want that column name should be selected daynamically throgh loop and then check the
condition for any update corresponding to that column value. I don't want to write as many if condition as the no. of column name. I just want one if condition for all column namesDon't be lazy. Write all column names into your trigger. Or use a way to create the trigger "dynamically".
What is the problem that you have with static column names? "I don't want to write many..." is not a problem, but an opinion. -
Trigger how to get new and old value for nested table column?
Hi,
I have created a nested table based on the following details:
CREATE TYPE typ_item AS OBJECT --create object
(prodid NUMBER(5),
price NUMBER(7,2) )
CREATE TYPE typ_item_nst -- define nested table type
AS TABLE OF typ_item
CREATE TABLE pOrder ( -- create database table
ordid NUMBER(5),
supplier NUMBER(5),
requester NUMBER(4),
ordered DATE,
items typ_item_nst)
NESTED TABLE items STORE AS item_stor_tab
INSERT INTO pOrder
VALUES (800, 80, 8000, sysdate,
typ_item_nst (typ_item (88, 888)));
Now I would like to create a trigger on table pOrder for after insert or update or delete
and I would like to track the new and old value for the columns inside nested table.
Can anybody direct me how to do it?
I would like to know the sytax for it like:
declare
x number;
begin
x := :new.nestedtablecolumn;--how to get the new and old value from nested table columns
end;
Hope my question is clear.
Thanks,
LavanHi,
Try like this:
CREATE OR REPLACE TRIGGER PORDER_I
BEFORE INSERT
ON PORDER
REFERENCING OLD AS old NEW AS new
FOR EACH ROW
DECLARE
items_new typ_item_nst;
ordid_NEW NUMBER;
BEGIN
FOR i IN :new.items.FIRST .. :new.items.LAST LOOP -- For first to last element
DBMS_OUTPUT.PUT_LINE(':new.items(' || I || ').prodid: ' || :new.items(I).prodid );
DBMS_OUTPUT.PUT_LINE(':new.items(' || I || ').price: ' || :new.items(I).price );
END LOOP;
END;Regards,
Peter -
Dynamically reference :old.column_ name in trigger
Hi all,
I am writing an application for which i would like to include a limited audit trail.
I have a form that is based on a table with approx 100 columns and wish to write the :old.column_name value on fields that have been updated, along with userid and date/time to an "audit" table.
I think that I can do this by using the Before_update trigger and then the IF UPDATING ('column name') condition. However, for maintenance and readabiility, I wish to be able to dynamically reference the :old.column_name value, which I cannot get working.
I know it can be done with a large IF statement, but due to the number of columns involved, this can lead to a maintenance nightmare. Also, if I can get this working, I want to include the procedure in a library for other applications, thus the need for dynamically referencing the table and column names.
My proposed logic for the before_update trigger is:
Declare Vcolumn_name Varchar2(50)
Get column names for table (using select cursor)
loop through cursor
Vcolumn_name := column name
IF UPDATING (Vcolumn_name) then
insert userid, timestamp, :old.Vcolumn_name into audit table
end IF
next cursor row
:old.Vcolumn_name is where I am having trouble.
Is this possible?
Thanks
PeterThe pre-update trigger won't store the value of the old.column . If you are querying the data and then updating then use the POST-QUERY trigger to store the current values in global variables. In the PRE-UPDATE trigger assign the global variables to the columns of the audit tables.
For instance in the PRE-FORM trigger initialize the global variables :
:GLOBAL.VAR1 := ' ';
:GLOBAL.VAR2 := ' ';
In the POST-QUERY trigger
:GLOBAL.VAR1 := :BLOCK.COLUMN1;
:GLOBAL.VAR2 := :BLOCK.COLUMN2;
In the PRE-UPDATE trigger
INSERT INTO AUDIT_TABLE (COL1, COL2)
VALUES(:GLOBAL.VAR1, :GLOBAL.VAR2);
Hope this helps. -
Dynamic build of a table trigger - Issue building :new and :old vars
(which leads me to my next issue - this one might be a deal killer for me; see "Are Optional Parameters possible in Procedural Units?"
I'm using a Select statement to dynamically create a table trigger which looks like the following:
create or replace trigger tr_audit#reporter
after update on reporter
for each row
begin
ttms_audit_pkg.insert_audit_info( 'reporter', 'ZIP', :new.ZIP, :old.ZIP, 'REPORTER.REPORTER,REPORTER.PROJECT_CD', 'EXFC', :new.reporter, :new.project_cd);
end;
The :new. and :old. variables are generated based on which table_name is passed to the script creating this trigger. My problem is that I need all the :new. and :old. parameters to be passed in as Char. regardless of whether they are Number or Date variables.
So in the example above...if :new.reporter is a number on the table then I need to to_char is like this:
create or replace trigger tr_audit#reporter
after update on reporter
for each row
begin
ttms_audit_pkg.insert_audit_info( 'reporter', 'ZIP', :new.ZIP, :old.ZIP,
'REPORTER.REPORTER,REPORTER.PROJECT_CD', 'EXFC', to_char(:new.reporter), :new.project_cd);
end;
However, since this trigger is created dynamically I will not know in advance which :new. and :old. parameters will need to be converted to character. So if to_char(:new.reporter) is used and :new.reporter is already a character on the table then I will get an error.
So my question then is this. Is there a way to write this dynamic sql in a way to accomidate this problem? I'm thinking something that would act a bit like a decode does with values...pehaps something like this:
decode(:new.reporter, NUMBER, to_char(:new.reporter), DATE, to_char(:new.reporter,'DD-MON-YYYY HH12:MIPM'), :new.reporter)
...if :new.reporter is a number then to_char it; if :new.reporter is a date then to_char it; otherwise let it be.
By any chance does anyone know if this is possible? I would greatly appreciate any insights.Sure, you can selectively version-enable tables using Workspace Manager (you call DBMS_WM.EnableVersioning on each table you want Workspace Manager to track history for).
What do you mean by "programmatically rollback changes"? Workspace Manager has the ability to call GotoTime and queries against a version-enabled table will return results as if you were querying it at that specific point in time (unless you've purged history of course). You can also use it to create what are essentially long-running transactions where you can work on multiple sets of proposed data changes simultaneously for days or months before finally deciding to commit a one particular set. It's incredibly powerful.
Justin -
Passing of old and new trigger details to a generic function or procedure
Hi all.
I have a requirement to pass all the new and old column information from a database trigger ( for the purposes of this discussion, it will be a before row, insert, update and delete trigger) to a procedure/function ( either is fine).
My first thought was to create a separate routine for each table I wish to implement this in, which has a new and old input parameter for every column, however I realised I needed a solution where the called routine needs to be generic (because we'll let other developers call the same routine and we dont want them to have to create their own version for their table).
This presents a problem as every table I wish to implement this on could have a completely different amount of columns (and dataypes). The called routine will operate under a pragma autnonmous_transaction (as it will be performing commits) so I need to pass all the fields across in one go.
Another idea I had was to create an type object with (potentially) 300 generic fields that I assign the values to and pass that as a parameter, however I could never know before hand what datatypes are needed, CLOBS, DATE, VARCHAR, etc...
Does anyone have any ideas on how I can accomplish this with a generic routine?
Regards,
Greg.Greg wrote:
I hadn't heard of the ANYDATA type, I'll have a lookThe Data Cartridge Developer's Guide has all the details - http://docs.oracle.com/cd/E11882_01/appdev.112/e10765/toc.htm
Here's a link that has some simple examples just for ANYDATA - http://orafaq.com/node/1853
TOOLKIT ALERT - Here is a classic link you will want to keep - How to pipeline a function with a dynamic number of columns?
I asked in another thread if they could create a locked TOOLKIT thread (like report abuse here - a global one for mods only) to put these nuggets in one place.
see ascheffer's responses where he shows how to create a pipelined function that call return a result set with a different (dnynamic) number of columns for different calls! It uses functionality in the
ANYTYPE - metadata
ANYDATA - data with metadata
ANYRESULTSET - A resultset where every column is of type ANYDATA - meaning whatever you define it to be.
Rough overview - The cartridge exposes some interface functions (3-5 are typically needed) that you implement in a procedure. See scheffer post for his procedure:
static function ODCITableDescribe( rtype out anytype, p_parm in varchar2, p_rows_req in number := 2 )
return number,
static function ODCITablePrepare( sctx out NColPipe, ti in sys.ODCITabFuncInfo, p_parm in varchar2, p_rows_req in number := 2 )
return number,
static function ODCITableStart( sctx in out NColPipe, p_parm in varchar2, p_rows_req in number := 2 )
return number,
member function ODCITableFetch( self in out NColPipe, nrows in number, outset out anydataset )
return number,
member function ODCITableClose( self in NColPipe )The TableDescribe does just what it's name says.
Oracle calls these functions to get the metadata about your custom types, to describe and return result sets.
Are you familiar with VARIANTs that are used in COM programming? A variant is a 16 byte object (record) type. 2 bytes contain the 'type' of the variant (int, char, etc) and other bytes contain data of that 'type'. It is a generic container that can hold any type of data.
The ANYTYPE, ANYDATA and ANYRESULTSET are roughly analogous to that. -
Dynamic references to trigger vars :new and :old
Is there any way to dynamicly refer to the :old and :new bind
variables available in triggers?
I'm looking for a method to make a standard processing system
that processes based on column-names. I want to avoid calling my
handling system staticly for each field in the table.
Ie. I want to refer to :old.data_column in a way where I can
loop through all the fields of the table.
Hints, tips and ideas would be greatly apprechiated.You can't have dynamic PL/SQL containing ":NEW" or ":OLD" in
database triggers.
But in some cases, if your table has primary key (PK)
or unique key (UK), you can use AFTER STATEMENT triggers
in following way
(this is like well-known solution for mutating error problem):
1. create database package with PL/SQL table
(for storing PK values)
2. clear PL/SQL table in BEFORE STATEMENT trigger
3. populate PL/SQL table with PK value
in BEFORE (or AFTER) ROW trigger
4. read rows in AFTER STATEMENT trigger with dynamic PL/SQL,
using PKs from PL/SQL table and using dynamically selected
column names with statement
SELECT column_name
FROM user_tab_columns
WHERE UPPER (table_name) = UPPER (p_table);"
(you can read NEW values of columns and,
with AUTONOMOUS_TRANSACTION, OLD values too)
For example (scott.dept table):
CREATE OR REPLACE TRIGGER bus_dept
BEFORE UPDATE ON dept
BEGIN
plsql_table.clear;
END;
CREATE OR REPLACE TRIGGER bur_dept
BEFORE UPDATE ON dept
FOR EACH ROW
BEGIN
plsql_table.populate_with_id (:NEW.deptno);
END;
CREATE OR REPLACE TRIGGER aus_dept
AFTER UPDATE ON dept
DECLARE
v_current_id dept.deptno%TYPE;
BEGIN
dynamic_new_old.set_table_name ('dept');
dynamic_new_old.set_pk_name ('deptno');
dynamic_new_old.create_column_names;
WHILE plsql_table.id_exists LOOP
v_current_id := plsql_table.current_id;
DBMS_OUTPUT.PUT_LINE ('OLD VALUES:');
dynamic_new_old.display_old_values (v_current_id);
DBMS_OUTPUT.PUT_LINE ('NEW VALUES:');
dynamic_new_old.display_new_values (v_current_id);
DBMS_OUTPUT.PUT_LINE ('*****');
END LOOP;
END;
CREATE OR REPLACE PACKAGE plsql_table IS
PROCEDURE clear;
PROCEDURE populate_with_id (p_id dept.deptno%TYPE);
FUNCTION id_exists RETURN BOOLEAN;
FUNCTION current_id RETURN dept.deptno%TYPE;
END;
CREATE OR REPLACE PACKAGE BODY plsql_table IS
TYPE type_plsql_table IS TABLE OF dept.deptno%TYPE INDEX BY
BINARY_INTEGER;
m_plsql_table type_plsql_table;
-- prefiks m_ is for module level variable (defined in package
body)
-- prefiks g_ is for global variable (defined in package
specification)
m_rec_number BINARY_INTEGER;
PROCEDURE clear IS
BEGIN
m_rec_number := 0;
END;
PROCEDURE populate_with_id (p_id dept.deptno%TYPE) IS
BEGIN
m_rec_number := m_rec_number + 1;
m_plsql_table (m_rec_number) := p_id;
END;
FUNCTION id_exists RETURN BOOLEAN IS
BEGIN
RETURN (m_rec_number > 0);
END;
FUNCTION current_id RETURN dept.deptno%TYPE IS
v_id dept.deptno%TYPE;
BEGIN
v_id := m_plsql_table (m_rec_number);
m_rec_number := m_rec_number - 1;
RETURN v_id;
END;
END;
CREATE OR REPLACE PACKAGE dynamic_new_old IS
PROCEDURE set_table_name (p_table VARCHAR2);
PROCEDURE set_pk_name (p_pk VARCHAR2);
PROCEDURE create_column_names;
PROCEDURE display_old_values (p_id dept.deptno%TYPE);
PROCEDURE display_new_values (p_id dept.deptno%TYPE);
END;
CREATE OR REPLACE PACKAGE BODY dynamic_new_old IS
m_table VARCHAR2 (30);
m_pk VARCHAR2 (30);
m_columns VARCHAR2 (1000);
PROCEDURE set_table_name (p_table VARCHAR2) IS
BEGIN
m_table := p_table;
END;
PROCEDURE set_pk_name (p_pk VARCHAR2) IS
BEGIN
m_pk := p_pk;
END;
PROCEDURE create_column_names IS
v_first_column BOOLEAN;
BEGIN
v_first_column := TRUE;
FOR rec IN
(SELECT column_name
FROM user_tab_columns
WHERE UPPER (table_name) = UPPER (m_table))
LOOP
IF v_first_column THEN
v_first_column := FALSE;
m_columns := 'v_record.' || rec.column_name;
ELSE
m_columns := m_columns ||
'||' || '''--''' || '|| v_record.' || rec.column_name;
END IF;
END LOOP;
END;
PROCEDURE display_values (p_id dept.deptno%TYPE) IS
v_cursor INTEGER;
v_rows_processed INTEGER;
v_statement VARCHAR2 (32000);
BEGIN
v_statement :=
' DECLARE ' ||
' v_record ' || m_table || '%ROWTYPE;' ||
' BEGIN' ||
' SELECT * INTO v_record' ||
' FROM ' || m_table ||
' WHERE ' || m_pk || ' = ' || p_id || ';' ||
' DBMS_OUTPUT.PUT_LINE (' || m_columns || ');' ||
' END;';
v_cursor := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE (v_cursor, v_statement, DBMS_SQL.V7);
v_rows_processed := DBMS_SQL.EXECUTE (v_cursor);
DBMS_SQL.CLOSE_CURSOR (v_cursor);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (sqlerrm);
IF DBMS_SQL.IS_OPEN (v_cursor) THEN
DBMS_SQL.CLOSE_CURSOR (v_cursor);
END IF;
END;
PROCEDURE display_old_values (p_id dept.deptno%TYPE) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
display_values (p_id);
END;
PROCEDURE display_new_values (p_id dept.deptno%TYPE) IS
BEGIN
display_values (p_id);
END;
END;
Note that this code is not generic, because uses
"dept.deptno%TYPE". If all your PKs has the same declaration
(for example NUMBER), then you can write generic solution.
If you need only OLD values, you can write a simpler solution
(without statement triggers and "plsql_table" package),
using "dynamic_new_old" package and AUTONOMOUS_TRANSACTION
in BEFORE (or AFTER) ROW trigger.
Regards
Zlatko Sirotic -
Delete after trigger returns a NULL value for the old primary key??
I am creat an After trigger that I was using to delete a row from another table. However, the OLD value returned for my primary key is a NULL value. I have an UPDATE and an INSERT portion to this same trigger that work fine with just grabbing NEW values, but this OLD value cannot be grabbed for some reason, although it seems to work on other tables when the owner is me, the problem table is not owned by me though. Has anyone run into this before? Is there a view that I need access to from this table or perhaps a setting I need to turn on? I am at a loss. Thanks.
Cannot reproduce with this modified trigger code ⦠right now I believe the problem is in this part:
BEGIN
col_ret := vpack.vOPCollectIO(tpid, User, 'SCOTT.OINFTABL', dmltype, vdata);
EXCEPTION
WHEN lost_connection OR lost_connection2 THEN
col_ret := vpack.vOPCollectIO(tpid, User, 'SCOTT.OINFTABL', dmltype, vdata);
END;
In schema CORE:
SQL> create table oinftabl
2 ( akey number(9) primary key
3 ,astring varchar2(10)
4 ,astring2 varchar2(10)
5 );
Table created.
SQL>
SQL> grant all on oinftabl to flip;
In schema FLIP (which has âCREATE ANY TRIGGERâ):
flip@FLOP> CREATE OR REPLACE TYPE VDAT AS VARRAY(100000) OF VARCHAR2(50);
2 /
create or replace trigger sbt3_system_oinftabl_x
after insert or update or delete on core.oinftabl
REFERENCING NEW as n OLD as o
FOR EACH ROW
DECLARE
col_ret INT;
dmltype CHAR(1);
tpid VARCHAR2(30);
vdata VDAT; --varray datatype I created;
lost_connection EXCEPTION;
lost_connection2 EXCEPTION;
already_there EXCEPTION;
PRAGMA EXCEPTION_INIT(lost_connection, -28576);
PRAGMA EXCEPTION_INIT(lost_connection2, -28579);
PRAGMA EXCEPTION_INIT(already_there,-1);
BEGIN
tpid := SYS.DBMS_TRANSACTION.LOCAL_TRANSACTION_ID();
IF INSERTING THEN dmltype := 'I';
ELSIF UPDATING THEN dmltype := 'U';
ELSE dmltype := 'D';
END IF;
IF INSERTING OR UPDATING THEN
dbms_output.put_line('new akey='||nvl(to_char(:n.akey),'null'));
dbms_output.put_line('new astring='||:n.astring);
vdata := VDAT(
to_char(:n.AKEY),
:n.ASTRING,
:n.ASTRING2,
NULL);
ELSIF DELETING THEN
dbms_output.put_line('old akey='||nvl(to_char(:o.akey),'null'));
vdata := VDAT(
to_char(:o.AKEY),
NULL);
END IF;
for i in 1..vdata.count
loop
dbms_output.put_line('vdata('||i||')='||nvl(vdata(i),'null'));
end loop;
--BEGIN
-- col_ret := vpack.vOPCollectIO(tpid, User, 'SCOTT.OINFTABL', dmltype, vdata);
--EXCEPTION
-- WHEN lost_connection OR lost_connection2 THEN
-- col_ret := vpack.vOPCollectIO(tpid, User, 'SCOTT.OINFTABL', dmltype, vdata);
--END;
END;
Trigger created.
flip@FLOP> show errors
No errors.
flip@FLOP> insert into core.oinftabl values (1,'abc',null);
new akey=1
new astring=abc
vdata(1)=1
vdata(2)=abc
vdata(3)=null
vdata(4)=null
1 row created.
flip@FLOP> update core.oinftabl set akey=2, astring='cba' where akey=1;
new akey=2
new astring=cba
vdata(1)=2
vdata(2)=cba
vdata(3)=null
vdata(4)=null
1 row updated.
flip@FLOP> delete from core.oinftabl where akey=2;
old akey=2
vdata(1)=2
vdata(2)=null
1 row deleted.
So the trigger has the OLD AKEY value when DELETING and it does successfully store it in the VARRAY.
Hence the problem is in that pl/sql block at the end.
What are you doing in there? -
Get old and new text of a VIEW at DDL trigger
Is it possible to get the old and the new text of a view at the DDL triggers
Hi,
Don't know regarding later Oracle versions but with 8.1.7.3.0 you cannot base system triggers on tables or views: Ora-30506.
Regards,
Andrew Velitchko
BrainBench MVP for Developer/2000
http://www.brainbench.com
Maybe you are looking for
-
How can you get music from your ipod for free
hi guys i want to get all the old music from my ipod onto my mac however there are loads of software that says it free then charges is there a way built into the mac system that alows me to do this like in terminal etc? i have mountain lion and am a
-
Effects: Level settings not rendered correctly in export
I am having the following issue in Premiere Pro CS5. I have an image sequence with alpha placed over some film footage. The sequence is supposed to blend with the real footage. To do so, I have adjusted the sequence with a few effect filters. The fil
-
Trick for making a iPhoto album "last loaded" in Flickr?
i have a set of albums published to Flickr and I have organized and added descriptions for all of these. i have one album that I would like Flickr to display as the most recently loaded images on my home screen but unfortunately i don't believe there
-
LACIE HD'S WONT MOUNT. APPLE THINKS I NEED A SEPERATE FIREWIRE CARD.
I have 2 lacie hd's that will not mount they used to mount but now they will not. I have been back and forth to the Mac store and I have been on the phone with Lacie . My drives were tested and my computer was tested and nothing is wrong WITH EITHER.
-
Problems after updating to iOS 6
After upgrating to iOS 6 I can't connect to the internet by cellular - only by WiFi. I have tried to take out and put in the SIM card again etc. without any result. Does anybody know what to do? Thanks