i have the following table
employee(id, pay-todate)
month_pay(employee_id(fk), hourly_pay_rate, hours_worked)
How would i go about creating a trigger that inserts
the total of(hourly_pay_rate x hours_worked) into pay-todate
whenever a new row is added to month_pay?
I also need to subtract 10% if the pay-todate is 10 000 or greater
delimiter |
CREATE TRIGGER insert_pay_trigger BEFORE INSERT ON month_pay
FOR EACH ROW BEGIN
insert into employee (id, `pay-todate`)
select NEW.employee_id,
case when NEW.hourly_pay_rate * NEW.hours_worked >= 100000
then NEW.hourly_pay_rate * NEW.hours_worked * 0.9
else NEW.hourly_pay_rate * NEW.hours_worked
end;
END
|
delimiter ;
Related
This is my first trigger in MySql and I am having a few problems. I tried both of these pieces of code but both would not compile. I got it to work without the where clause.
CREATE TRIGGER ins_meal_details
AFTER INSERT ON meal_details
FOR EACH ROW
INSERT INTO sql_changes
SET
sc_table='book_room',
sc_reason='DINNER1',
sc_key='bh_no=NEW.bh_no,date=NEW.md_date',
sc_value='1',
sc_done =0
WHERE not exists (select 1 from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1)
CREATE TRIGGER ins_meal_details AFTER INSERT meal_details FOR EACH ROW
BEGIN
IF NOT EXISTS (select 1 from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1) THEN
INSERT INTO sql_changes (sc_table, sc_reason, sc_key, sc_value, sc_done )
VALUES ('book_room','DINNER1', 'bh_no=NEW.bh_no,date=NEW.md_date','1', 0);
END IF
END
CREATE TRIGGER ins_meal_details
AFTER INSERT
ON meal_details
FOR EACH ROW
INSERT INTO sql_changes (sc_table,
sc_reason,
sc_key,
sc_value,
sc_done)
SELECT 'book_room',
'DINNER1',
CONCAT('bh_no=',NEW.bh_no,',date=',NEW.md_date),
1,
0
WHERE NOT EXISTS (SELECT 1
FROM booking
WHERE bh_no = NEW.bh_no
AND bo_date = NEW.md_date
AND bo_meals < 1);
MySql did not like the select/where exists in my code when there is no table specified. This was due to using version 5.6 of MySql server.
This will not work: select 'works' where exists (select 1 from my-table)
The fix would be thanks to #akina to add from DUAL. The best solution.
I got round it by using a count(*) instead :-
DROP TRIGGER IF EXISTS ins_meal_details;
DELIMITER //
CREATE TRIGGER ins_meal_details
AFTER INSERT ON meal_details FOR EACH ROW
BEGIN
IF (select count(*) from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1) > 0 THEN
INSERT INTO sql_changes (sc_table,
sc_reason,
sc_key,
sc_value,
sc_done)
VALUES ('book_room','DINNER1', CONCAT('bh_no=',NEW.bh_no,',date=',NEW.md_date),'New Value', 0);
END IF;
END//
DELIMITER ;
I am using MYSQL 5.7.19 on ubuntu 16.04 (local mashine). I have 2 tables schema:
CREATE TABLE raw (rdate DATE, pim int(3));
CREATE TABLE indx (idate DATE, ipim int(2));
INSERT INTO raw (rdate, pim)
VALUES (20000101,50), (20000201, 52);
INSERT INTO indx (idate, ipim)
VALUES (20000101,5), (20000201, 5);
Table raw is for monthly data date and pim numbers. I want to write the trigger - before insert which will compare new pim with latest (is new pim higher or lower compared to previous pim value) and then according to number ranges (for example: if pim is between 40 and 50 than ipim = 5) insert particular number into column ipim in table indx and the new rdate into new idate.
Here is my trigger code:
DELIMITER //
CREATE TRIGGER sortpim BEFORE INSERT ON raw
FOR EACH ROW
BEGIN
DECLARE new_pim,old_pim,max_d INT;
SET new_pim = NEW.pim;
SET old_pim = (SELECT pim FROM raw WHERE rdate > CURDATE());
IF (old_pim <= new_pim) THEN
CASE WHEN new_pim BETWEEN 50 AND 59 THEN
INSERT INTO indx(idate,ipim) VALUES(NEW.rdate,6);
WHEN new_pim BETWEEN 60 AND 70 THEN
INSERT INTO indx(idate,ipim) VALUES(NEW.rdate,7);
END CASE;
ELSEIF (old_pim > new_pim) THEN
CASE
WHEN new_pim BETWEEN 50 AND 60 THEN
INSERT INTO indx(idate,ipim) VALUES(NEW.rdate,5);
WHEN new_pim BETWEEN 40 AND 49 THEN
INSERT INTO indx(idate,ipim) VALUES(NEW.rdate,4);
END CASE;
END IF;
END; //
DELIMITER ;
The trigger code is accepted with no errors but when I try to trigger it by inserting new record into raw table:
INSERT INTO raw(rdate,pim) VALUES(20000301,55);
record is inserted with no errors and the trigger does not do anything - the indx table is not inserted with new record.
I'm new in MYSQL thus it is likely I choose wrong logic or methods. And it could be mistakes in algorithm or syntax. Any suggestions to solve this is appreciated. Thanx.
UPDATE!
Thanx for suggestions and point where are my mistake.
I have found the solution for getting the latest date as there was the mistake in trigger code on line 7. Here is what works:
` SELECT pim FROM raw ORDER BY rdate DESC LIMIT 1; `
I have a table, f_gas:
id - int, auto inc
date - date
volume - int
kwh - int
kwh is calculated from the volume and some other variables, which I will later place into a different table. So, when I insert a new row with a meter reading (date and volume) I wish for it to run the calculation to determine the actual energy usage (kwh).
(All this because my energy supplier gives me absolutely nothing in usage data!)
CREATE TRIGGER gas_kwh
BEFORE INSERT ON f_gas
FOR EACH ROW BEGIN
SET NEW.kwh = (NEW.volume * 2.83 * 39.5 * 1.02264 / 3.6)
END;
I've also tried:
CREATE TRIGGER gas_kwh
BEFORE INSERT ON f_gas
FOR EACH ROW BEGIN
SET NEW.kwh = (NEW.volume * 2.83 * 39.5 * 1.02264 / 3.6);
END;
Both are syntax errors and I am not sure exactly why (the error console is non specific as to where the syntax error lies). I've also tried escaping the field names in backticks to no avail. I'm not exactly new to MySQL but I am new to triggers. Where am I going wrong?
The trigger's syntax is correct. It is possible that MySQL client cannot parse statements. You need to use DELIMITER command, e.g.:
DELIMITER $$
CREATE TRIGGER gas_kwh
BEFORE INSERT
ON f_gas
FOR EACH ROW
BEGIN
SET NEW.kwh = (NEW.volume * 2.83 * 39.5 * 1.02264 / 3.6);
END
$$
DELIMITER ;
Article about DELIMITER - What is the DELIMITER in MySQL and what it’s used for.
Also, for your trigger you can do this -
CREATE TRIGGER gas_kwh
BEFORE INSERT
ON f_gas
FOR EACH ROW
SET NEW.kwh = (NEW.volume * 2.83 * 39.5 * 1.02264 / 3.6);
I'm building some application, which is connected to mysql database.
In mysql in let say table test I have an Integer field called myId.
With my first insert to the myId value "1" is added, with my second insert i'm adding value "20".
Now my question is: is there any possibility, that to the first value "1" after second insert will be auto added "0".
So i will have:
|myId|
10
20
And if a add "300", so to the two first inserts will be added next 0 ?
|myId|
100
200
300
Just do it when you select data
set #max:=(select max(length(myId)) from your_table);
SELECT myId * power(10, (#max - length(myId))) from table;
unverified:
delimiter |
CREATE TRIGGER upd_entries AFTER INSERT ON your_table
FOR EACH ROW
BEGIN
update your_table
set myId = myId * power(10, ((select * from (select max(length(myId)) from your_table)) - length(myId)));
END;
|
delimiter ;
I've read that this can be done without issue using MyISAM as it is the default behavior , but I'm using InnoDB so need a trigger for such.
The two PK fields are batch and lineItem. If a record is deleted I want the numbering to start from the largest integer for batch. Not fill in the holes.
This is to set up a testing environment for a legacy system. So the schema is the way it is, I thought I'd mention that to avoid any discussion about whether it is good or not.
Edit: I want something like the following insert statement as a trigger
INSERT INTO payroll(`batch`,`lineItem`)
(select 'T105',t1.lineItem + 1 from payroll as t1 where batch = 'T105' order by lineItem desc limit 1);
But where 'T105' (the batch id) is hard coded I want the trigger to pick that up from the insert.
So I want to be able to say something like:
INSERT INTO payroll(`batch`)VALUES('T001','T001','T001', 'T002', 'T002', 'T002');
and I would expect to see in the table:
batch lineItem
T001 1
T001 2
T001 3
T002 1
T002 2
T002 3
Getting further:
In trying to implement this I've come up with:
DELIMITER $$
CREATE TRIGGER `co05_test`.`ins_lineItem`
BEFORE INSERT ON `co05_test`.`my_table`
FOR EACH ROW
BEGIN
select lineItem + 1 into #newLineItem from my_table where batch = NEW.batch order by lineItem desc limit 1;
set NEW.lineItem = #newLineItem;
END$$
However when I try...
INSERT INTO `co05_test`.`my_table`(`batch`)VALUES('T001');
I get this error: Column 'lineItem' cannot be null
Which is defined as not being nullable but I though the trigger should set the value!
Solution which I used:
-- Trigger DDL Statements
DELIMITER $$
USE `co05_test`$$
CREATE TRIGGER `co05_test`.`ins_lineItem`
BEFORE INSERT ON `co05_test`.`my_table`
FOR EACH ROW
BEGIN
select count(*) into #batchCount from my_table where batch = NEW.batch;
select lineItem + 1 into #newLineItem from my_table where batch = NEW.batch order by lineItem desc limit 1;
if #batchCount > 0 then
set NEW.lineItem = #newLineItem;
else
set NEW.lineItem = 1;
end if;
END;
$$
Have you tried declaring the variable instead?
DELIMITER $$
CREATE TRIGGER `co05_test`.`ins_lineItem`
BEFORE INSERT ON `co05_test`.`my_table`
FOR EACH ROW
BEGIN
DECLARE newLineItem INT;
SELECT
lineItem + 1 into newLineItem
FROM my_table
WHERE batch = NEW.batch
ORDER BY lineItem DESC
LIMIT 1;
SET NEW.lineItem = newLineItem;
END$$