trigger using oracle sql developer - triggers

I am using the trigger for insert value in the new table but when i try that i cant insert value in the salaud (new table)
CREATE OR REPLACE TRIGGER trigcom
BEFORE update of comm,salary on staff
for EACH ROW
when (old.comm <= (0.25*old.salary))
begin
insert into salaud (emp_id,s_date,salary,commission,error_code)
values(:new.id,sysdate,:new.salary,:new.comm,'rule a');
end;
enter image description here
this one is my original table
enter image description here
that is my new table i want to insert the value in here through the condition
i tried almost all way in the google but i cant find the way

Related

Trigger that updates stock levels after a sale - MySQL Workbench

I am trying to create a trigger called 'stockupdate' that updates 'quantity_available' when a new order is placed on my order_line_item_table.
Tables and columns required: stock_table.quantity_available (Represents Stock) order_line_item_table.sale_quantity (Represents each order placed)
I have used the below code to create the trigger, however when I insert a new order to check the trigger is working, the stock_table.quantity_available figure does not update and I am not sure why. Any help would be greatly appreciated.
DELIMITER $$
DROP TRIGGER IF EXISTS stockupdate;
CREATE TRIGGER stockupdate
AFTER INSERT ON order_line_item_table
FOR EACH ROW
BEGIN
UPDATE stock_table
SET quantity_available = (quantity_available - NEW.sale_quantity)
WHERE product_id = NEW.product_id;
END$$
DELIMITER ;
I am expecting the quantity_available to decrease by the sale_quantity amount when a new order is placed on the order_line_item_table

Track Changes in Source table and load to History Table

I have created a view which has columns that i need to track for any change and load it into a history table. I created a Trigger as below and when i execute change, it only updates the History but does not add a new updated record. Any idea what im doing wrong?
create or replace function asset_h_fn() returns trigger
LANGUAGE plpgsql
as $$
begin
if (asset = 'Insert') then
insert into asset_history (sys_period,col1,col2,col3,col4,col5,col6)
values (tstzrange(lower(OLD.sys_period), current_timestamp), OLD.col1, OLD.col2, OLD.col3, OLD.col4, OLD.col5);
NEW.sys_period = tstzrange(current_timestamp,null);
return new;
return old;
end if;
end $$ ;
The RETURN OLD; in your code is fortunately unreachable; remove it.
You don't show us the CREATE TRIGGER statement, but it must be an INSTEAD OF trigger.
A view does not hold any data, it is an SQL statement with a name. So if you want a new row to appear in the view, you have to add a second INSERT to the trigger function that inserts a row into the table(s) on which the view is defined.
Well, It depends on how do you define your trigger...
Looking at your code I suppose you should use CREATE TRIGGER <trigger_name> BEFORE INSERT OR UPDATE ON <table_name> FOR EACH ROW EXECUTE PROCEDURE asset_h_fn();
The key here is BEFORE INSERT - if you wish to alter somehow inserted into original table data... If you don't wish to alter it, you should probably use AFTER INSERT.
You may read more about defining triggers and see some examples in official docs

Get data of multiple inserted rows in one object using trigger in postgres

I am trying to write a trigger which gets data from the table attribute in which multiple rows are inserted corresponding to one actionId at one time and group all that data into the one object:
Table Schema
actionId
key
value
I am firing trigger on rows insertion,SO how can I handle this multiple row insertion and how can I collect all the data.
CREATE TRIGGER attribute_changes
AFTER INSERT
ON attributes
FOR EACH ROW
EXECUTE PROCEDURE log_attribute_changes();
and the function,
CREATE OR REPLACE FUNCTION wflowr222.log_task_extendedattribute_changes()
RETURNS trigger AS
$BODY$
DECLARE
_message json;
_extendedAttributes jsonb;
BEGIN
SELECT json_agg(tmp)
INTO _extendedAttributes
FROM (
-- your subquery goes here, for example:
SELECT attributes.key, attributes.value
FROM attributes
WHERE attributes.actionId=NEW.actionId
) tmp;
_message :=json_build_object('actionId',NEW.actionId,'extendedAttributes',_extendedAttributes);
INSERT INTO wflowr222.irisevents(message)
VALUES(_message );
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
and data format is,
actionId key value
2 flag true
2 image http:test.com/image
2 status New
I tried to do it via Insert trigger, but it is firing on each row inserted.
If anyone has any idea about this?
I expect that the problem is that you're using a FOR EACH ROW trigger; what you likely want is a FOR EACH STATEMENT trigger - ie. which only fires once for your multi-line INSERT statement. See the description at https://www.postgresql.org/docs/current/sql-createtrigger.html for a more through explanation.
AFAICT, you will also need to add REFERENCING NEW TABLE AS NEW in this mode to make the NEW reference available to the trigger function. So your CREATE TRIGGER syntax would need to be:
CREATE TRIGGER attribute_changes
AFTER INSERT
ON attributes
REFERENCING NEW TABLE AS NEW
FOR EACH STATEMENT
EXECUTE PROCEDURE log_attribute_changes();
I've read elsewhere that the required REFERENCING NEW TABLE ... syntax is only supported in PostgreSQL 10 and later.
Considering the version of postgres you have, and therefore keeping in mind that you can't use a trigger defined FOR EACH STATEMENT for your purpose, the only alternative I see is
using a trigger after insert in order to collect some information about changes in a utility table
using a unix cron that execute a pl/sql that do the job on data set
For example:
Your utility table
CREATE TABLE utility (
actionid integer,
createtime timestamp
);
You can define a trigger FOR EACH ROW with a body that do something like this
INSERT INTO utilty values(NEW.actionid, curent_timestamp);
And, finally, have a crontab UNIX that execute a file or a procedure that to something like this:
SELECT a.* FROM utility u JOIN yourtable a ON a.actionid = u.actionid WHERE u.createtime < current_timestamp;
// do something here with records selected above
TRUNCATE table utility;
If you had postgres 9.5 you could have used pg_cron instead of unix cron...

Import CSV into Postgres: Update & Insert at the same time

So I´m fairly new to Postgresql and started working with it by testing out some stuff with pgadmin4 on Postgres9.6.
The problem:
I have a table: test(id, text)
In this table I have 10 rows of data.
Now I want to import a CSV which has 12 rows to update the test table. Some text changed for the first 10 rows AND I want to insert the 2 additional rows from the CSV.
I know that you can truncate all the data from a table and just import everything again from the CSV, but that´s not a nice way to do this. I want to Update my existing data & Insert the new data with one query.
I already found a function which should solve this by using a temporary table. This updates the existing rows correct, but the 2 additional rows do not get inserted
CREATE OR REPLACE FUNCTION upsert_test(integer,varchar) RETURNS VOID AS $$
DECLARE
BEGIN
UPDATE test
SET id = tmp_table.id,
text = tmp_table.text
FROM tmp_table
WHERE test.id = tmp_table.id;
IF NOT FOUND THEN
INSERT INTO test(id,text) values
(tmp_table.id,tmp_table.text);
END IF;
END;
$$ Language 'plpgsql';
DO $$ BEGIN
PERFORM upsert_test(id,text) FROM test;
END $$;
So what do I need to change to also get the insert to work?
Assuming you have a primary or unique constraint on the id column you can do this with a single statement, no function required:
insert into test (id, text)
select id, text
from tmp_table
on conflict (id)
do update set text = excluded.text;

How to create a Trigger in PostgreSql?

TRIGEER-->To get a column value from one table to other table when i insert values?
I am having two tables(customer_details and loan_balance).
What i need is, I must get the column (custid)of customer_details table to the loan_balance table when i insert the data into the loan_balance table.
This is the full set up of my query : SQL FIDDLE
So i need a trigger to be raised and the data should be updated automatically without dynamic insertion of custid.
Postgres has an unconventional way of creating triggers:
create a function that returns type trigger and return the NEW row record
create a trigger that executes the function
Here's the code you need:
CREATE FUNCTION synch_custid_proc()
RETURNS trigger AS $$
BEGIN
NEW.custid = (
select max(custid)
from customer_details
where creditid = NEW.creditid
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql
CREATE TRIGGER synch_custid_trig
BEFORE INSERT ON loan_amount
FOR EACH ROW
EXECUTE PROCEDURE synch_custid_proc();
I chosen to select max(custid) rather than simply custid when finding the value in case there are multiple rows that match. You might have to adjust this logic to suit your data.
See a live demo on SQLFiddle