Concatenate String with a column in trigger - oracle

I have a table called TBL_CAS. In that, FLD_ID as auto increment column and another column is called FLD_CAS_CODE. Now I need to add CAS- as a prefix to FLD_ID and Insert into FLD_CAS_CODE. I need to do this in trigger. I was tried with the below code, But the data in not inserting, What is the problem ?
CREATE OR REPLACE TRIGGER TBL_CAS_TRG
BEFORE INSERT ON TBL_CAS
FOR EACH ROW
BEGIN
:NEW.FLD_CAS_CODE := TO_CHAR ('CAS')||'-'||:NEW.FLD_ID;
END;
I mean `"cas-"+"fld_id"="cas-fld_id"'

You don't need to put TO_CHAR() around things which are already charcater datatypes. But you should cast the numeric identifier (rather than relying on implicit conversion):
:NEW.FLD_CAS_CODE := 'CAS-'||TRIM(TO_CHAR (:NEW.FLD_ID));

which part isn't working exactly? as your trigger seem to work just fine.
SQL> create table TBL_CAS( FLD_ID number, FLD_CAS_CODE varchar2(20));
Table created.
SQL> CREATE OR REPLACE TRIGGER TBL_CAS_TRG
2 BEFORE INSERT ON TBL_CAS
3 FOR EACH ROW
4 BEGIN
5 :NEW.FLD_CAS_CODE := TO_CHAR ('CAS')||'-'||:NEW.FLD_ID;
6 END;
7 /
Trigger created.
SQL> insert into TBL_CAS (fld_id) values (1001);
1 row created.
SQL> select * From TBL_CAS;
FLD_ID FLD_CAS_CODE
---------- --------------------
1001 CAS-1001
SQL>

This will also work fine:
CREATE OR REPLACE TRIGGER TBL_AREA_CODES_TRG
BEFORE INSERT ON TBL_AREA_CODES
FOR EACH ROW
BEGIN
:NEW.OBRM_AREA_CODE := :NEW.STATE_CODE ||'-'||:NEW.DIST_CODE ||'-'||:NEW.CITY_CODE ||'-'||:NEW.AREA_CODE ;
END;

Related

Is before update trigger will fire if same values are updating into a row of column

I am using before update trigger for each row on table, say emp_table to update one column modifid_date before loading into table. If I am going to update the table with same/existing values of a row, then is this trigger going to fire or not?
condition in trigger:
:new.modifid_dt := sysdate;
Table Values before update: john (name),4867 (id),20-04-2016 (modifid_dt)
Table values now going to update: john (name),4867 (id)
Your trigger will be fired, no matter the values you are using; for example:
SQL> create table testTrigger ( a number)
2 /
Table created.
SQL> CREATE OR REPLACE TRIGGER before_update_trigger
2 before update on testTrigger
3 for each row
4 begin
5 dbms_output.put_line('Trigger fired!');
6 end;
7 /
Trigger created.
SQL> insert into testTrigger values (10);
1 row created.
SQL>
SQL>
SQL> update testTrigger set a = 10;
Trigger fired!
1 row updated.
SQL> update testTrigger set a = 11;
Trigger fired!
1 row updated.
SQL>
If you want avoid "false" firing you should write trigger like this:
create or replace trigger trigger1
before update on tst
for each row
begin
IF :new.t_key != :old.t_key AND ... THEN
dbms_output.put_line('Trigger fired!');
END IF;
end;
But beware of NULL values, of course.
New or existing values - no matter, anyway you'll perform an update so trigger will fire.

Oracle trigger to update a column value in the same table

I am in the need of a trigger which will fire on any insert or updates on the specific table and while inserting or updating will substitute a credit card number column of the new row to something bogus such as "1111 1111 1111 1111"
Here is what I cooked up but it doesn't seem to work.
CREATE or REPLACE TRIGGER trigger_name AFTER INSERT ON table1
FOR EACH ROW
BEGIN
update table1 set cc_number_field = '11';
END;
I am on Oracle 10 if that matters.
It's much easier to manipulate the incoming :NEW line with a "before" trigger:
CREATE OR REPLACE TRIGGER table1_cc_trigger
BEFORE INSERT OR UPDATE ON table1
FOR EACH ROW
BEGIN
:NEW.cc_number_field := '1111 1111 1111 1111';
END;
/
Not tested:
CREATE OR REPLACE TRIGGER t
BEFORE
INSERT on ON table1 FOR EACH ROW
begin
:new.cc_number_field = '11';
END;
PL/SQL Reference - Triggers

Creating a trigger on Oracle 11g

I need to create a trigger that updates another table whenever the trigger table has an insert into command, or an after insert trigger.
I need to pull the id that's being inserted into the table in order to update the other table, how do I go about doing so?
In case that's confusing, another attempt at my question:
Table 1 has an after insert trigger. Said trigger updates table 2 based on one of the id values being inserted into table 1. How do I pull said id value from table 1 in the trigger?
You can use :new in your trigger to reference the values being inserted, for example
create or replace trigger <trigger_name>
after insert on <table_name>
for each row
declare
l_id number;
begin
select :new.id into l_id from dual;
-- now l_id contains the id of the inserted row, do what you want with it
end;
Don't take the example to literally; you don't have to first select :new.id into a variable, you can use it directly in SQL inside the trigger. I did it here just for illustration.
Take a look at the Oracle docs: Coding Triggers
However, you might also want to take a look at some arguments why you should think twice if you really need to put your logic into triggers: The Trouble with Triggers
CREATE OR REPLACE TRIGGER testempdel
AFTER insert ON testemp
FOR EACH ROW
BEGIN
update testdelvalues set salary=:New.sal;
END;
/
Trigger created.
Initially the salary is null
SQL> select * from testdelvalues;
EMPNO EMPNAME SALARY
---------- ---------- ----------
7369 SMITH
After inserting the value in the other table is updated
SQL> insert into testemp (empno,ename,sal) values (1231,'TESTUSER',1000);
1 row created.
SQL> select * from testdelvalues;
EMPNO EMPNAME SALARY
---------- ---------- ----------
7369 SMITH 1000

Oracle create trigger error (bad bind variable)

I at trying to create trigger with the following code.
CREATE OR REPLACE TRIGGER MYTABLE_TRG
BEFORE INSERT ON MYTABLE
FOR EACH ROW
BEGIN
select MYTABLE_SEQ.nextval into :new.id from dual;
END;
I am getting error
Error(2,52): PLS-00049: bad bind variable 'NEW.ID'
Any ideas? Thanks.
It seems like the error code is telling you there's no such column ID in your table...
Somehow your environment is treating your code as SQL instead of a DDL statement. This works for me (running in sqlplus.exe from a command prompt):
SQL> create sequence mytable_seq;
Sequence created.
SQL> create table mytable (id number);
Table created.
SQL> CREATE OR REPLACE TRIGGER MYTABLE_TRG
2 BEFORE INSERT ON MYTABLE
3 FOR EACH ROW
4 BEGIN
5 select MYTABLE_SEQ.nextval into :new.id from dual;
6 END;
7 /
Trigger created.
Note the trailing "/" - this might be important in the application you are compiling this with.
if one would use proper naming convention the spotting of this type
of errors would be much easier ( where proper means using pre- and postfixes )
for generic object names hinting about their purpose better
i.e. something like this would have spotted the correct answer
--START -- CREATE A SEQUENCE
/*
create table "TBL_NAME" (
"TBL_NAME_ID" number(19,0) NOT NULL
, ...
*/
--------------------------------------------------------
-- drop the sequence if it exists
-- select * from user_sequences ;
--------------------------------------------------------
declare
c int;
begin
select count(*) into c from user_sequences
where SEQUENCE_NAME = upper('SEQ_TBL_NAME');
if c = 1 then
execute immediate 'DROP SEQUENCE SEQ_TBL_NAME';
end if;
end;
/
CREATE SEQUENCE "SEQ_TBL_NAME"
MINVALUE 1 MAXVALUE 999999999999999999999999999
INCREMENT BY 1 START WITH 1
CACHE 20 NOORDER NOCYCLE ;
-- CREATE
CREATE OR REPLACE TRIGGER "TRG_TBL_NAME"
BEFORE INSERT
ON "TBL_NAME"
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
DECLARE
tmpVar NUMBER;
BEGIN
tmpVar := 1 ;
SELECT SEQ_TBL_NAME.NEXTVAL INTO tmpVar FROM dual;
:NEW.TBL_NAME_ID := tmpVar;
END TRG_TBL_NAME;
/
ALTER TRIGGER "TRG_TBL_NAME" ENABLE;
-- STOP -- CREATE THE TRIGGER
If you're like me and your code should be working, try dropping the trigger explicitly before you re-create it. Stupid Oracle.

Oracle PL/SQL: Forwarding whole row to procedure from a trigger

In have an Oracle (10i) PL/SQL Row-Level trigger which is responsible for three independent tasks. As the trigger is relatively cluttered that way, I want to export these three tasks into three stored procedures.
I was thinking of using a my_table%ROWTYPE parameter or maybe a collection type for the procedures, but my main concern is how to fill these parameters.
Is there a way to put the whole :NEW row of a trigger into a single variable easily?
So far the only way I could find out was assigning each field separately to the variable which is not quite satisfying, looking at code maintenance etc.
Something like
SELECT :NEW.* INTO <variable> FROM dual;
would be preferred. (I haven't tried that actually but I suppose it wouldn't work)
In the vast majority of cases, the only way to assign the new values in the row to a %ROWTYPE variable would be to explicitly assign each column. Something like
CREATE OR REPLACE TRIGGER some_trigger_name
BEFORE INSERT OR UPDATE ON some_table
FOR EACH ROW
DECLARE
l_row some_table%rowtype;
BEGIN
l_row.column1 := :NEW.column1;
l_row.column2 := :NEW.column2;
...
l_row.columnN := :NEW.columnN;
procedure1( l_row );
procedure2( l_row );
procedure3( l_row );
END;
If your table happens to be declared based on an object, :NEW will be an object of that type. So if you have a table like
CREATE OR REPLACE TYPE obj_foo
AS OBJECT (
column1 NUMBER,
column2 NUMBER,
...
columnN NUMBER );
CREATE TABLE foo OF obj_foo;
then you could declare procedures that accept input parameters of type OBJ_FOO and call those directly from your trigger.
The suggestion in the other thread about selecting the row from the table in an AFTER INSERT/ UPDATE thread, unfortunately, does not generally work. That will generally lead to a mutating table exception.
1 create table foo (
2 col1 number,
3 col2 number
4* )
SQL> /
Table created.
SQL> create procedure foo_proc( p_foo in foo%rowtype )
2 as
3 begin
4 dbms_output.put_line( 'In foo_proc' );
5 end;
6 /
Procedure created.
SQL> create or replace trigger trg_foo
2 after insert or update on foo
3 for each row
4 declare
5 l_row foo%rowtype;
6 begin
7 select *
8 into l_row
9 from foo
10 where col1 = :new.col1;
11 foo_proc( l_row );
12 end;
13 /
Trigger created.
SQL> insert into foo values( 1, 2 );
insert into foo values( 1, 2 )
*
ERROR at line 1:
ORA-04091: table SCOTT.FOO is mutating, trigger/function may not see it
ORA-06512: at "SCOTT.TRG_FOO", line 4
ORA-04088: error during execution of trigger 'SCOTT.TRG_FOO'
It's not possible that way.
Maybe my answer to another question can help.
Use SQL to generate the SQL;
select ' row_field.'||COLUMN_NAME||' := :new.'||COLUMN_NAME||';' from
ALL_TAB_COLUMNS cols
where
cols.TABLE_NAME = 'yourTableName'
order by cols.column_name
Then copy and paste output.
This is similar to Justins solution but a little bit shorter (no typing of left part of each assignment) :
-- use instead of the assignments in Justins example:
select :new.column1,
:new.column2,
...
:new.columnN,
into l_row from dual;

Resources