PL/SQL trigger to insert next value - sql

I created a trigger which works like when I update/insert a row in one table, an insert of a row will a done in another table which contains a primary key.
Now when I insert a row in the first table I want the trigger to check the last value of primary key of another table and if that is null or '-' then I've to insert 1 into that primary key column so as to insert the remaining values.
I've written the code as follows:
create or replace trigger "T1"
AFTER
insert or update on "buses"
for each row
begin
-- Here I want to check the V_id on vehicles table, if that is null or '-' then insert V_id as 1 along with the below insert statement.
if :NEW."b_key" is not null then
INSERT INTO vehicles (b_KEY,B_NAME,ADDRESS_1,CITY,STATE,ZIP,PHONE,WEBSITE) VALUES (:new.b_KEY,:new.b_NAME,:new.ADDRESS_1,:new.CITY,:new.STATE,:new.ZIP,:new.PHONE,:new.WEBSITE);
end if;
end;
How to find the last b_id in the vehicles table, so that if that value is null or '-' insert b_id as 1, followed by the above insert statement in the same row.

By adding another trigger we can do that as follows:
create or replace TRIGGER "B_VEHICLES"
before insert on "buses"
for each row
declare b_number number;
begin
select max(B_ID) into b_number from Vehicles;
if :OLD."B_ID" is null and b_number is null then
select 1 into :new."B_ID" from dual;
else select b_number + 1 into :new."B_ID" from dual;
end if;
end;​

Related

Trigger with insert and calculations

I Have two tables, TableA which has a primary key (A_ID) and a salary column.
Table B has a primary key (B_ID) and a paymentAmount column.
I need to create a trigger so that once TableB B_ID is inserted the trigger will go to TableA, find A_ID which matches B_ID, grab the salary on the relating column then divide it by 12 and finally add the result of that calculation to TableB paymentAmount column.
Here is my attempt but it does not compile;
CREATE TRIGGER test AFTER INSERT ON TableB
FOR EACH ROW
BEGIN
UPDATE TableB
SET TableB.paymentamount = TableA.salary / 12 WHERE TableA.staffid = TableB.staffid
END;
I've never used triggers before so apologies if this I'm going about this the wrong way.
I think that this does what you want:
create trigger test before insert on tableb
for each row
declare
v_salary number;
begin
select salary into v_salary from tablea a where a.a_id= :new.b_id;
:new.paymentamount := v_salary / 12;
end;
/
In a nutshell: this is a before trigger that modifies the paymentamount in the row that is about to be inserted. To get the relevant value, we query tablea for the row whose a_id matches the newly inserted b_id and recover the corresponding salary, that we assign to a variable.

I need to create 3 rows in Student_Fee table when 1 row is inserted in Student table using trigger

Following is the trigger
Create TRIGGER [dbo].[Student]
ON [dbo].[Student]
After INSERT
AS
BEGIN
Insert Into Student_Fee([StudentID],[InstID],[PersonID],[FeeSubmiteTime],[FeeMsg],[Type])
Select NULL,3,PersonID,getdate(),'Student submitted on','Student' from INSERTED
END
I need to create 3 rows in Student_Fee table when 1 row is inserted in Student table.First row in Student_fee must have StudentID Null and for other two rows student ID is filled obtained from previous table. Also, Feemsg should be different for the 3 rows. It is text and could be any value. And for type there are two types Student and Admin and the types are also not fixed. They can vary while inserting rows.
How can I do that by using trigger?
here you go :
CREATE TABLE Temp1abhari (
id INT identity(1, 1)
,number INT
);
CREATE TABLE Temp2abhari (
id INT
,number INT
);
CREATE TRIGGER TTemp1abhari ON Temp1abhari
FOR INSERT
AS
BEGIN
INSERT INTO Temp2abhari
VALUES (
NULL
,1
);
INSERT INTO Temp2abhari
SELECT ID
,2
FROM Inserted;
INSERT INTO Temp2abhari
SELECT ID
,3
FROM Inserted;
END

Delete data using SQL Partitioning

I want to create a table implementing partition function such that if the number of records becomes 5+1 then the first recor gets deleted For example if the records are 1,2,3,4,5 and we insert 6th record then 1st record gets deleted and remaining records are 2,3,4,5,6
After your Insert you could add something like:
delete from mytable
where RecordID <= select(MAX(RecordID)-5 from mytable);
So that everything before the 5 most recent rows are deleted.
You could use a trigger after insert to delete the surplus rows. Try this example:
BEGIN TRANSACTION;
SET NOCOUNT ON;
create table t (id int identity(1,1), val char(1))
go
create trigger limit_t on t for insert as
begin
if (select count(*) from t) > 5
delete from t where id <= (select max(id)-5 from t);
end
go
-- insert five rows
insert t (val) values ('a'),('b'),('c'),('d'),('e')
-- insert a sixth and seventh row
insert t (val) values ('f'),('g')
-- retrieve content after last insert
select * from t
-- the table now holds values [c,d,e,f,g]
ROLLBACK TRANSACTION;

Get ID of last inserted row and use it to insert into another table in a stored procedure

I have the following stored procedure which we use to insert data into a table:
CREATE OR REPLACE PROCEDURE mySproc
(
invoiceId IN NUMBER
customerId IN NUMBER
)
IS
BEGIN
INSERT INTO myTable (INVOICE_ID)
VALUES (invoiceId);
END mySproc;
/
What I am trying to do is to get the last inserted ID (this is the primary key field on myTable and auto incremented using a sequence) and insert it into another table, I have tried the following but could not get it working:
CREATE OR REPLACE PROCEDURE mySproc
(
invoiceId IN NUMBER
customerId IN NUMBER
)
IS
BEGIN
INSERT INTO myTable (INVOICE_ID)
VALUES (invoiceId)
returning id into v_id;
INSERT INTO anotherTable (ID, customerID)
VALUES (v_id, customerId);
END mySproc;
/
I am getting this error: [Error] PLS-00049 (59: 26): PLS-00049: bad bind variable 'V_ID' I think I need to declare v_id somewhere but I tried before and after the BEGIN statement but that gave another error.
Any ideas as to how to do this?
Thanks
Change your procedure to
CREATE OR REPLACE PROCEDURE mySproc
(
invoiceId IN NUMBER, -- Added comma
customerId IN NUMBER
)
IS
v_id NUMBER; -- ADDED
BEGIN
INSERT INTO myTable (INVOICE_ID)
VALUES (invoiceId)
returning id into v_id;
INSERT INTO anotherTable (ID, customerID)
VALUES (v_id, customerId);
END mySproc;
Share and enjoy.

Insert/Update in PL/SQL

I have made a procedure in PL/SQL which inserts data from one table to another on basis of primary key. My procedure is working fine but i can't figure out how will i update column CODE_NUMBER of my table MAIN if primary key already exists.
Actually i want rows of MAIN table to get UPDATED when its has primary key and insert data from REGIONS when primary key does not exists.
DECLARE
variable number;
id number;
description varchar2 (100);
CURSOR C1 IS
select regions.REGION_ID variable
from regions;
BEGIN
FOR R_C1 IN C1 LOOP
BEGIN
select regions.REGION_ID,regions.REGION_NAME
into id,description
from regions
where regions.REGION_ID = R_C1.variable;
----If exists then update otherwise insert
INSERT INTO MAIN( ID, CODE_NUMBER) VALUES( id,description);
dbms_output.put_line( id ||' '|| 'Already Exists');
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
dbms_output.put_line( R_C1.variable);
END;
END LOOP;
END;
There's no need to do this with PL/SQL and cursors. What you really want to do is something like this:
MERGE INTO MAIN dst
USING (
SELECT regions.REGION_ID id,
regions.REGION_NAME description
FROM regions
) src
ON src.id = dst.id
WHEN MATCHED THEN UPDATE
SET dst.code_number = src.description
WHEN NOT MATCHED THEN INSERT (id, code_number)
VALUES (src.id, src.description)
Read more about the SQL MERGE statement in the documentation
I can not really see a point in doing a cursor in this case. Why can't you just do it like this:
--Update the rows
UPDATE MAIN
SET ID=regions.REGION_ID,
CODE_NUMBER=regions.[description]
FROM MAIN
JOIN regions
ON MAIN.ID=regions.REGION_ID;
--Insert the new ones
INSERT INTO MAIN(ID,CODE_NUMBER)
SELECT
regions.REGION_ID,
regions.[description]
FROM
regions
WHERE NOT EXISTS
(
SELECT
NULL
FROM
MAIN.ID=regions.REGION_ID
)