How to create the views using trigger? - sql

Ca you please suggest if I can create the db view using triggers in Oracle?
E.g. I have a trigger trig_cust and I want to create a view:
Create or replace view vw_cust as select * from trig_cust;
P.S. need to use this view in loop

Triggers are an even of action. You cannot create a view out of trigger.
Triggers are used to perform an action insert/ update / delete based on particular event where as views are used to select set of columns with the combination of multiple tables.
View is used to display a combined set of required columns from various tables in order to reduce the querying effort. View is majorly used for reporting purpose. You can have a trigger on the view, but not view out of trigger.

suggest if I can create the db view using triggers in Oracle?
Can you? Yes, you can. Should you? No, you shouldn't.
Anyway, just for amusement, here you go: table and its trigger which is supposed to create a view once a new row is inserted into a table. Pay attention to pragma; without it, it wouldn't work as you can't commit in a trigger. True, there's no explicit commit there, but create view is a DDL and it implicitly commits.
SQL> create table test (empno number, ename varchar2(20));
Table created.
SQL> create or replace trigger trg_ai_test
2 after insert on test
3 for each row
4 declare
5 pragma autonomous_transaction;
6 begin
7 execute immediate 'create or replace view v_test_' || to_char(:new.empno) ||
8 ' as select * from test where empno = ' || :new.empno;
9 end;
10 /
Trigger created.
Testing:
SQL> insert into test (empno, ename) values (1, 'Little');
1 row created.
SQL> insert into test (empno, ename) values (2, 'Foot');
1 row created.
SQL> select * from v_test_1;
EMPNO ENAME
---------- --------------------
1 Little
SQL> select * from v_test_2;
EMPNO ENAME
---------- --------------------
2 Foot
SQL>

Related

How can I get the table name in a Oracle trigger function?

How can I get the table name inside trigger function?
Something similar to TG_TABLE_NAME in Postgres, like this
Oracle 10g or above.
That's user_triggers view (if I understood the question correctly).
SQL> create table test (id number, name varchar2(20));
Table created.
SQL> create or replace trigger trg_test
2 before insert on test
3 for each row
4 begin
5 null;
6 end;
7 /
Trigger created.
SQL> select trigger_name, table_name from user_triggers;
TRIGGER_NAME TABLE_NAME
------------------------------ ------------------------------
TRG_TEST TEST --> this is the one I've just created
TRG_AIUD_EMP EMPLOYEES
SQL>

Oracle trigger multiple conditions in when clause

I'm trying to create a trigger that updates a column in a table when other columns are updated. but getting the following error while saving the trigger
ORA-25000: invalid use of bind variable in trigger WHEN clause
My trigger is as follows, I'm not sure what is wrong with the code.
CREATE OR REPLACE TRIGGER Employees_ARIU
BEFORE INSERT OR UPDATE ON Employees
FOR EACH ROW
WHEN ((nvl(:OLD.EMP_SAL,0) != nvl(:NEW.EMP_SAL,0)) OR (nvl(:OLD.SAL_LEVEL,0) != nvl(:NEW.SAL_LEVEL,0)))
BEGIN
:NEW.LAST_UPDATED = SYSDATE
END;
Although IF is an alternative to WHEN, I'd say that it is better to use WHEN clause whenever possible because it is a
SQL condition that must be satisfied for the database to fire the trigger
So, why would you even let the trigger fire and then conclude that oh, OK, I don't want to do anything, after all? Better not running it at all!
Yes, WHEN clause has its restrictions and you can't put anything you want in there, but - your case isn't one of those.
(more info in Documentation, search for "WHEN clause").
So, for a sample table
SQL> create table employees
2 (id number,
3 emp_sal number,
4 sal_level number,
5 last_updated date);
Table created.
trigger would looks like this:
SQL> create or replace trigger employees_ariu
2 before insert or update on employees
3 for each row
4 when ( nvl(old.emp_sal, 0) <> nvl(new.emp_sal, 0)
5 or nvl(old.sal_level, 0) <> nvl(new.sal_level, 0)
6 )
7 begin
8 :new.last_updated := sysdate;
9 end;
10 /
Trigger created.
Testing:
SQL> insert into employees (id, emp_sal, sal_level) values (1, 100, 1);
1 row created.
SQL> select * from employees;
ID EMP_SAL SAL_LEVEL LAST_UPDATED
---------- ---------- ---------- -------------------
1 100 1 12.06.2021 12:14:17
SQL> update employees set sal_level = 2 where id = 1;
1 row updated.
SQL> select * from employees;
ID EMP_SAL SAL_LEVEL LAST_UPDATED
---------- ---------- ---------- -------------------
1 100 2 12.06.2021 12:14:33
SQL>
I think you can try updating your WHEN condition to IF statement along with few other changes -
CREATE OR REPLACE TRIGGER Employees_ARIU
BEFORE INSERT OR UPDATE ON Employees
FOR EACH ROW
BEGIN
IF ((nvl(:OLD.EMP_SAL,0) != nvl(:NEW.EMP_SAL,0)) OR (nvl(:OLD.SAL_LEVEL,0) != nvl(:NEW.SAL_LEVEL,0))) then
:NEW.LAST_UPDATED := SYSDATE;
END IF;
END;
/
Here is the fiddle.

trying to create a trigger

I want to create a trigger that will store the timing of when a new row is inserted into a my employee's table.
so far this is my code, but i keep getting errors.
trigger:
CREATE OR REPLACE TRIGGER insert_new_employee
AFTER INSERT ON employees
BEGIN
insert into audit_cheker (date_create) values (sysdate());
END;
my table to store the timing for when inserting a new element:
create table audit_cheker(
date_create date
)
the error I've received is
00000 - "trigger '%s.%s' is invalid and failed re-validation"
Cause:
A trigger was attempted to be retrieved for execution and was
found to be invalid. This also means that compilation/authorization
failed for the trigger.
Action:
Options are to resolve the compilation/authorization errors,
disable the trigger, or drop the trigger.
Based on information you posted so far, it should work. Here's a test case:
SQL> create table audit_cheker
2 (date_create date);
Table created.
SQL> create table employees as select empno, ename, deptno From emp;
Table created.
Trigger:
SQL> CREATE OR REPLACE TRIGGER insert_new_employee
2 AFTER INSERT ON employees
3 BEGIN
4 insert into audit_cheker (date_create) values (sysdate());
5 END;
6 /
Trigger created.
No problems so far. Let's test it:
SQL> insert into employees (empno, ename, deptno) values (1, 'LF', 10);
1 row created.
SQL> select * from employees where empno = 1;
EMPNO ENAME DEPTNO
---------- ---------- ----------
1 LF 10
SQL> select * From audit_cheker;
DATE_CREATE
----------------
2020-04-24 07:18
As you can see, it works.
If trigger is invalid, try to recompile it:
SQL> alter trigger insert_new_employee compile;
Trigger altered.
If it still doesn't help, please, edit your initial message (the question you posted) and copy/paste your SQL*Plus session so that we could see what you did and how Oracle responded.

Why do I get the "bad bind variable" error when trying to create an INSTEAD OF trigger in PL/SQL Oracle?

I have these 4 tables:
Suppliers( id_sup, name, city)
Products (id_prod, name, city)
Companies (id_co, name, city)
Deliveries (id_sup, id_prod, id_co)
I created a view for Deliveries called "v_deliveries" and I want to create an instead of trigger so that if someone tries inserting data in the view, it will actually add it to the Deliveries table. This is what i've tried:
CREATE OR REPLACE TRIGGER new_deliv_trigg
INSTEAD OF INSERT ON v_deliveries FOR EACH ROW
BEGIN
INSERT INTO Deliveries (id_sup, id_prod, id_co)
VALUES (:NEW.id_sup, :NEW.id_prod, :NEW.id_co);
End;
Which database do you really use? Because, as for Oracle, it works OK:
SQL> create table deliveries (id_sup number, id_prod number, id_co number);
Table created.
SQL> create or replace view v_deliveries as select * From deliveries;
View created.
SQL>
SQL> CREATE OR REPLACE TRIGGER new_deliv_trigg
2 INSTEAD OF INSERT ON v_deliveries FOR EACH ROW
3 BEGIN
4 INSERT INTO Deliveries (id_sup, id_prod, id_co)
5 VALUES (:NEW.id_sup, :NEW.id_prod, :NEW.id_co);
6 End;
7 /
Trigger created.
SQL>

Create Auto Sequence text and number in oracle 11g

How I do create column ID with value JASG1?
I am only find example like this :
select 'JASG'||to_char(mtj_id_seq.nextval) from talend_job
Although what you wrote probably works (if there's a sequence named MTJ_ID_SEQ, you have a privilege to select from it; the same goes for the TALEND_JOB table), I'd say that it isn't what you should use.
Here's why: I'll create a table and a sequence. Table will be pre-populated with some IDs (just to put something in there).
SQL> create sequence mtj_id_seq;
Sequence created.
SQL> create table talend_job as
2 select rownum id from dept;
Table created.
SQL> select * from talend_job;
ID
----------
1
2
3
4
OK; 4 rows so far. Now, run your SELECT:
SQL> select 'JASG'||to_char(mtj_id_seq.nextval) from talend_job;
'JASG'||TO_CHAR(MTJ_ID_SEQ.NEXTVAL)
--------------------------------------------
JASG1
JASG2
JASG3
JASG4
SQL> select 'JASG'||to_char(mtj_id_seq.nextval) from talend_job;
'JASG'||TO_CHAR(MTJ_ID_SEQ.NEXTVAL)
--------------------------------------------
JASG5
JASG6
JASG7
JASG8
SQL>
See? You didn't get only 1 JASGx value, but as many as number of rows in the TALEND_JOB table. If there was a million rows, you'd get a million JASGx rows as well.
Therefore, maybe you meant to use DUAL table instead? E.g.
SQL> select 'JASG'||to_char(mtj_id_seq.nextval) from dual;
'JASG'||TO_CHAR(MTJ_ID_SEQ.NEXTVAL)
--------------------------------------------
JASG9
SQL> select 'JASG'||to_char(mtj_id_seq.nextval) from dual;
'JASG'||TO_CHAR(MTJ_ID_SEQ.NEXTVAL)
--------------------------------------------
JASG10
SQL>
See? Only one value.
Also, notice that sequences will provide unique values, but you can't rely on them being gapless.
As you mentioned "how to create column ID" - one option is to use a trigger. Here's an example:
SQL> create table talend_job (id varchar2(20), name varchar2(20)
Table created.
SQL> create or replace trigger trg_bi_tj
2 before insert on talend_job
3 for each row
4 begin
5 :new.id := 'JASG' || mtj_id_seq.nextval;
6 end;
7 /
Trigger created.
Let's insert some names; IDs should be auto-populated by the trigger:
SQL> insert into talend_job (name) values ('littlefoot');
1 row created.
SQL> insert into talend_job (name) values ('Ishak');
1 row created.
SQL> select * From talend_job;
ID NAME
-------------------- --------------------
JASG11 littlefoot
JASG12 Ishak
SQL>
OK then; now you have some more info - read and think about it.
By the way, what is the "compiler-errors" tag used for? Did you write any code and it failed? Perhaps you'd want to share it with us.