I have table Inventory
"INVENTORY_CODE" VARCHAR2(20) NOT NULL ENABLE
"ITEM_CODE" VARCHAR2(20) NOT NULL ENABLE
"WAREHOUSE_CODE" VARCHAR2(20)
"CON_TON" NUMBER(38,5)
"IN_Q_TON" NUMBER(38,5)
"OR_Q_TON" NUMBER(38,5)
"RES_TON" NUMBER(38,5)
"RET_TON" NUMBER(38,5)
"ST_INV" NUMBER(38,5)
and another table Inventory_warehouse
"CODE" VARCHAR2(20) NOT NULL ENABLE
"ITEM_CODE" VARCHAR2(20) NOT NULL ENABLE
"QUANTITY_AV_TON" NUMBER(38,5)
"QUANTITY_AV_REAM" NUMBER(38,5)
"QUANTITY_AV_SHEET" NUMBER(38,5)
I want to make a trigger to calculate QUANTITY_AV_TON
as
QUANTITY_AV_TON = IN_Q_TON + RES_TON + RET_TON + ST_INV - CON_TON - OR_Q_TON
I created this trigger but it didn't work
create or replace trigger QUANTITY_TON
AFTER insert or update or delete on INVENTORY
for each row
begin
UPDATE INVENTORY_WAREHOUSE
SET QUANTITY_AV_TON =
select (IN_Q_TON + RES_TON + RET_TON + ST_INV - CON_TON -OR_Q_TON)
from inventory
where INVENTORY.item_code = INVENTORY_WAREHOUSE.item_code;
end;
the values of IN_Q_TON , RES_TON , RET_TON , ST_INV , CON_TON ,OR_Q_TON are calculated from other tables using triggers
If you want to perform the calculation from the context values of the row in the trigger that is being processed. This is normally done by using the ":NEW" variable. I have edited the trigger, but cannot run it, so please try it out. Please read the Oracle Trigger Docs
CREATE OR REPLACE TRIGGER QUANTITY_TON
AFTER INSERT OR UPDATE OR DELETE
ON INVENTORY
FOR EACH ROW
BEGIN
UPDATE INVENTORY_WAREHOUSE
SET QUANTITY_AV_TON = :new.IN_Q_TON
+ :new.RES_TON
+ :new.RET_TON
+ :new.ST_INV
- :new.CON_TON
- :new.OR_Q_TON
WHERE INVENTORY_WAREHOUSE.ITEM_CODE = :new.ITEM_CODE;
END;
Related
I have to call a trigger which updates fields of total and percentage after query is inserted
heres the code
create table bhrugus1 (
student_name varchar2(100),
dbms number,
dsa number,
mco number,
total number,
percentage number,
roll_no number primary key
);
CREATE OR REPLACE TRIGGER trial1
AFTER INSERT on bhrugus1
REFERENCING new AS new
FOR EACH ROW
BEGIN
:new.total := :new.dbms + :new.dsa + :new.mco;
:new.percentage := (:new.dbms + :new.dsa + :new.mco) / 3 ;
END;
insert into bhrugus1 values ('bhrugu',90,90,90,1,1,2);
SELECT * from bhrugus1;
the table and while running trigger i get error
the new error
Please modify your trigger:
CREATE OR REPLACE TRIGGER trial1
before INSERT on bhrugus1
REFERENCING new AS new
FOR EACH ROW
BEGIN
:new.total := :new.dbms + :new.dsa + :new.mco;
:new.percentage := (:new.dbms + :new.dsa + :new.mco) / 3 ;
END;
You shouldn't run an update statement in your trigger, use the :new... instead of update.
The other important thing is:
before insert
You are missing a component, what happens when someone UPDATEs any or all of dbms,dsa,mco. There is no update trigger to recalculate total or percentage. You could of course just include 'OR UPDATE' on the trigger. A better way however would be defining them a virtual columns.
create table bhrugus1 (
student_name varchar2(100),
dbms number,
dsa number,
mco number,
total number generated always as (dbms+dsa+mco) virtual,
percentage number generated always as ((dbms+dsa+mco)/3) virtual,
roll_no number primary key
);
With that both total and percentage (bad name it is the average - but that is another issue) will always calculated properly. And drop the trigger it is no longer needed.
I have a trigger named tr_admin_user_role that automatically insert values into tbl_user_role table when we perform a insert in another table called tbl_admin. There is no error at compile time but whenever I insert a value into tbl_admin table it shows me an error and error is like
This is my tbl_admin table
CREATE TABLE tbl_admin(
admin_id INTEGER,
username VARCHAR2(50) NOT NULL UNIQUE,
passwords VARCHAR2(50) NOT NULL,
email VARCHAR2(100) UNIQUE,
enabled CHAR(1) DEFAULT 1 NOT NULL,
created_at DATE DEFAULT SYSDATE NOT NULL,
CONSTRAINT pk_admin_id PRIMARY KEY(admin_id)
);
tbl_user_role table
CREATE TABLE tbl_user_role(
user_role_id INTEGER,
username VARCHAR2(50) NOT NULL,
user_role VARCHAR2(50) DEFAULT 'ROLE_ADMIN' NOT NULL,
CONSTRAINT pk_user_role_id PRIMARY KEY(user_role_id)
);
Trigger that i have created
CREATE OR REPLACE TRIGGER tr_admin_user_role
AFTER INSERT ON tbl_admin
FOR EACH ROW
DECLARE
new_username TBL_ADMIN.username%TYPE;
BEGIN
SELECT username INTO new_username FROM (
SELECT username FROM tbl_admin ORDER BY username DESC
) WHERE ROWNUM = 1;
INSERT INTO tbl_user_role(username, user_role) VALUES(new_username, 'ROLE_ADMIN');
END;
Insert statement
INSERT INTO tbl_admin(username, passwords) VALUES('nisha', 'nisha');
That's not how you fetch the newly inserted / updated / previous value of a column in a Trigger. You should use the :OLD.column_name and :NEW.column_name to refer the old and new column values.Read the documentation to understand more.
So, your Trigger could be rewritten as
CREATE OR REPLACE TRIGGER tr_admin_user_role AFTER
INSERT ON tbl_admin
FOR EACH ROW
BEGIN
INSERT INTO tbl_user_role (
username,
user_role
) VALUES (
:NEW.username,
'ROLE_ADMIN'
);
END;
/
I assume you are using another trigger to generate
admin_id and user_role_id since they are declared as PRIMARY KEYs
and you are not including them in your inserts.
Db fiddle demo
Here I've used dummy values for those columns.
How to increment the value of the unique constraint column value in ORACLE, in the select statement.
For example, in a table 'BILLING_TABLE' - column BLNG_Sk is the unique key (Autoincremented).
So while inserting a new record into the BILLING_TABLE, for the column BLNG_SK we need to give the value (Which is the increment by 1 from the present max value.)
For example, if BLNG_SK max value is 12321.
new record should be 12322.
how to achieve this in Oracle?
Oracle has a SEQUENCE object which provides the functionality you require.
You create one using the CREATE SEQUENCE SQL statement.
The Oracle documentation provides all the required information and the documentation is available via Oracle's Web site.
Assuming you are on Oracle 12.1 or later, define it as an identity column and do not pass any value when inserting:
create table testtable
( test_id number generated always as identity
constraint testtable_pk primary key
, othercol varchar2(10) );
insert into testtable (othercol) values ('Demo');
select * from testtable;
TEST_ID OTHERCOL
---------- ----------
1 Demo
insert into testtable (othercol) values ('Demo #2');
select * from testtable;
TEST_ID OTHERCOL
---------- ----------
1 Demo
2 Demo #2
Try creating a sequence and a trigger. This is the case when you provide the value manually.
CREATE SEQUENCE dept_seq START WITH 12322;
Trigger definition:
CREATE OR REPLACE TRIGGER dept_bir
BEFORE INSERT ON BILLING_TABLE
FOR EACH ROW
BEGIN
SELECT dept_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
/
Is there anyway that we can set a constraint in database table level to have upper or lower case values for certain columns? When we create a table, we can set NOT NULL to avoid having null values on a column. Same way, can we do that for either uppercase or lower case?
You can do that using a check constraint:
create table foo
(
only_lower varchar(20) not null check (lower(only_lower) = only_lower),
only_upper varchar(20) not null check (upper(only_upper) = only_upper)
);
I had almost same case, tried with check constraint, but if the user is not mentioning it as UPPER() or LOWER() it gives error so I took TRIGGER route as below code.
--creating table
create table user_name (
first_name varchar2(50),
last_name varchar2(50));
--creating trigger
CREATE OR REPLACE TRIGGER TRG_USER_NAME_IU
BEFORE INSERT OR UPDATE ON USER_NAME
FOR EACH ROW
BEGIN
:NEW.FIRST_NAME := UPPER(:NEW.FIRST_NAME);
:NEW.LAST_NAME := UPPER(:NEW.LAST_NAME);
END;
/
Can test and share feedback or comments
I have an Oracle Table with the following keys: ID, Name, DoB, Dept & FileNo. The ID field is the primary Key with an Auto Incremented value.
I wish to write a trigger, so that when a row is added with the Name, DoB & Dept , the FileNo field should get the value yyyy/xxxx where 'yyyy' is a predefined string & 'xxxx' is the value in ID field.
How do I do this?
If it will always be the ID with some prefix, then it probably shouldn't be a column. If that is the default, then a trigger that sets :new.fileno := 'string'||:new.id should suffice.
Oracle doesn't have auto increment, so you probably mean a sequence. If you have a trigger populating that, then this can go in the same trigger.
You need a sequence to implement an Auto Incremented value:
create sequence seq_file_id start with 1 increment by 1;
and a trigger on a table
CREATE TRIGGER file_trg
BEFORE insert
ON file_table
FOR EACH ROW
BEGIN
SELECT seq_file_id.NEXTVAL INTO :new.id FROM dual;
:NEW.fileno := 'yyyy' || :new.id;
END;
/