Add two timestamp variable in mysql trigger - mysql

I have written my trigger like this
CREATE TRIGGER `update_total_duration` AFTER UPDATE ON `sales_activity`
FOR EACH ROW thisTrigger:BEGIN
IF(NEW.activity_id=4)
THEN LEAVE thisTrigger;
ELSEIF NOT EXISTS
(SELECT 1 FROM sales_duration_update WHERE user_id = NEW.user_id AND date = CURDATE())
THEN INSERT INTO sales_duration_update (user_id,date,total_duration) VALUES (NEW.user_id,CURDATE(),NEW.duration);
ELSE
//problem is here when total_duration = total_duration + NEW.duration
UPDATE sales_duration_update SET total_duration = total_duration + NEW.duration WHERE user_id = NEW.user_id AND date = CURDATE();
END IF;
END
Problem is here in code
total_duration = total_duration + NEW.duration
where both variable are timestamp variable.How can I add two timestamp variables in trigger?

I found the answer.May be will help someone.
CREATE TRIGGER `update_total_duration` AFTER UPDATE ON `sales_activity`
FOR EACH ROW thisTrigger:BEGIN
IF(NEW.activity_id=4)
THEN LEAVE thisTrigger;
ELSEIF NOT EXISTS
(SELECT 1 FROM sales_duration_update WHERE user_id = NEW.user_id AND date = CURDATE())
THEN
INSERT INTO sales_duration_update (user_id,date,total_duration) VALUES (NEW.user_id,CURDATE(),NEW.duration);
ELSE
UPDATE sales_duration_update SET total_duration = ADDTIME(total_duration, NEW.duration) WHERE user_id = NEW.user_id AND date = CURDATE();
END IF;

Related

Mysql Procedure IF,ELSEIF Statment error

I try to create a procedure in mysql, but i get an syntax error, i don`t know why i get it and where is ''
# 1064 - You have an error in the RSQL syntax next to '' on line 4
My Procedure:
CREATE PROCEDURE MUWAP_VipAdd(IN szCharName varchar(10),IN DayAdd int,IN VipType smallint,IN datenow_srv datetime)
BEGIN
IF NOT EXISTS (SELECT 1 FROM `T_VIPList` WHERE AccountID = szCharName) THEN
INSERT INTO `T_VIPList` (`AccountID`,`Date`,`Type`) VALUES (szCharName,DATE_ADD(datenow_srv, INTERVAL DayAdd DAY),VipType);
ELSE IF EXISTS (SELECT 1 FROM `T_VIPList` WHERE AccountID = szCharName AND Date > datenow_srv) THEN
UPDATE `T_VIPList` SET `Date` = DATE_ADD(`Date`,INTERVAL DayAdd DAY) WHERE `AccountID` = szCharName;
UPDATE `T_VIPList` SET `Type` = VipType WHERE `AccountID` = szCharName AND `Type` < VipType;
ELSE
UPDATE `T_VIPList` SET `Date` = DATE_ADD(`Date`,INTERVAL DayAdd DAY), `Type` = VipType WHERE `AccountID` = szCharName;
END IF
END
Thank you!
In order to have multiple statements in a THEN statement, you need to use BEGIN...END.
CREATE PROCEDURE MUWAP_VipAdd(IN szCharName varchar(10),IN DayAdd int,IN VipType smallint,IN datenow_srv datetime)
BEGIN
IF NOT EXISTS (SELECT 1 FROM `T_VIPList` WHERE AccountID = szCharName)
THEN INSERT INTO `T_VIPList` (`AccountID`,`Date`,`Type`) VALUES (szCharName,DATE_ADD(datenow_srv, INTERVAL DayAdd DAY),VipType);
ELSE IF EXISTS (SELECT 1 FROM `T_VIPList` WHERE AccountID = szCharName AND Date > datenow_srv)
THEN BEGIN
UPDATE `T_VIPList` SET `Date` = DATE_ADD(`Date`,INTERVAL DayAdd DAY) WHERE `AccountID` = szCharName;
UPDATE `T_VIPList` SET `Type` = VipType WHERE `AccountID` = szCharName AND `Type` < VipType;
END
ELSE UPDATE `T_VIPList` SET `Date` = DATE_ADD(`Date`,INTERVAL DayAdd DAY), `Type` = VipType WHERE `AccountID` = szCharName;
END IF
END
You could also combine the two UPDATE queries into a single query:
UPDATE T_VIPList
SET Date = DATE_ADD(Date, INTERVAL DayAdd DAY),
Type = GREATEST(VipType, Type)
WHERE AccountID = szCharName;
In fact, it seems like the whole thing could be done with a single INSERT ... ON DUPLICATE KEY UPDATE query:
INSERT INTO T_VIPList (AccountID, Date, Type)
VALUES (szCharName,DATE_ADD(datenow_srv, INTERVAL DayAdd DAY),VipType)
ON DUPLICATE KEY UPDATE
Date = IF(Date > datenow_srv, VALUES(Date), Date),
Type = GREATEST(Type, VALUES(Type));

Rewrite MySQL Trigger to Postgres

guys!
I have a trigger in MySQL database:
CREATE DEFINER="root"#"127.0.0.1" TRIGGER `tai_actions_for_active_count` AFTER INSERT ON `actions` FOR EACH ROW BEGIN
DECLARE l_isnn TINYTEXT;
IF NEW.action_type IN ('CREATION', 'VERIFICATION', 'CLOSE') THEN
SET l_isnn = IF(NEW.isnn is NULL, '*', NEW.isnn);
IF NOT NEW.action_type = 'CLOSE' THEN
INSERT INTO subscriptions.`statistics_active_count`(`service_id`, `operator_id`, `isnn`, `active_count`)
VALUES (NEW.service_id, NEW.operator_id, l_isnn, 1)
ON DUPLICATE KEY UPDATE active_count = active_count + 1;
ELSE
SET #tai_actions_for_active_count = -1;
UPDATE subscriptions.`statistics_active_count` SET active_count = #tai_actions_for_active_count := active_count - 1
WHERE `service_id` = NEW.service_id AND `operator_id` = NEW.operator_id AND `isnn` = l_isnn;
IF #tai_actions_for_active_count = 0 THEN DELETE FROM subscriptions.`statistics_active_count` WHERE `active_count` = 0; END IF;
END IF;
END IF;
END
So I need to rewrite it to make it works in Postgres database. As there's ON DUPLICATE KEY UPDATE I'm using Postgres version 9.5 with UPSERT (ON CONFLICT (KEY) DO UPDATE).
So I poorly know SQL language can you tell me what I'm doing wrong? There's the Postgres PL code:
DECLARE
l_isnn TEXT;
tai_actions_for_active_count INTEGER;
BEGIN
IF NEW.action_type IN ('CREATION', 'VERIFICATION', 'CLOSE') THEN
IF NEW.isnn is NULL THEN
l_isnn := '*';
ELSE
l_isnn := NEW.isnn;
END IF;
IF NOT NEW.action_type = 'CLOSE' THEN
INSERT INTO "subscriptions.statistics_active_count"(service_id, operator_id, isnn, active_count)
VALUES (NEW.service_id, NEW.operator_id, l_isnn, 1)
ON CONFLICT(active_count) DO UPDATE SET active_count = active_count + 1;
ELSE
tai_actions_for_active_count := -1;
UPDATE "subscriptions.statistics_active_count" SET active_count = active_count - 1
-- (tai_actions_for_active_count := active_count - 1)
WHERE service_id = NEW.service_id AND operator_id = NEW.operator_id AND isnn = l_isnn;
UPDATE "subscriptions.statistics_active_count" SET tai_actions_for_active_count = active_count
WHERE service_id = NEW.service_id AND operator_id = NEW.operator_id AND isnn = l_isnn;
IF tai_actions_for_active_count = 0 THEN DELETE FROM "subscriptions.statistics_active_count" WHERE active_count = 0; END IF;
END IF;
END IF;
RETURN NULL;
END;
As I want to test this trigger I'm getting an error -- relation "subscriptions.statistics_active_count" does not exist
Can you help me with that code?
Finally I've got the solution. I guess :)
BEGIN
IF NEW.action_type IN ('CREATION', 'VERIFICATION', 'CLOSE') THEN
IF NEW.isnn IS NULL THEN
l_isnn := '*';
ELSE
l_isnn := NEW.isnn;
END IF;
IF NOT NEW.action_type = 'CLOSE' THEN
BEGIN
INSERT INTO subscriptions.statistics_active_count (service_id, operator_id, isnn, active_count)
VALUES (NEW.service_id, NEW.operator_id, l_isnn, 1);
EXCEPTION WHEN unique_violation THEN
UPDATE subscriptions.statistics_active_count SET active_count = active_count + 1
WHERE service_id = NEW.service_id and operator_id=NEW.operator_id;
END;
ELSE
tai_actions_for_active_count := -1;
WITH upd AS
(UPDATE subscriptions.statistics_active_count
SET active_count = active_count - 1
WHERE service_id = NEW.service_id AND operator_id = NEW.operator_id AND isnn = l_isnn;
RETURNING active_count)
SELECT *
FROM upd INTO tai_actions_for_active_count;
IF tai_actions_for_active_count = 0 THEN
DELETE FROM public.statistics_active_count
WHERE active_count = 0;
END IF;
END IF;
END IF;
END;

Date is not getting set

I have a procedure that should always set a date, but it does not:
CREATE PROCEDURE 'player_extend_membership` (pid INTEGER, daysToAdd INTEGER, OUT result INTEGER)
BEGIN
SELECT PlayerMembershipEndDate INTO #memDate FROM players WHERE players.PlayerID = pid LIMIT 1;
SELECT ROW_COUNT() INTO #num;
IF #num = 0 THEN
SET result = -1;
ELSE
IF #memDate = NULL OR DATE(#memDate) < DATE(NOW()) THEN
SET #finalDate = DATE_ADD(DATE(NOW()), INTERVAL daysToAdd DAY);
ELSE
SET #finalDate = DATE_ADD(DATE(#memDate), INTERVAL daysToAdd DAY);
END IF;
SELECT #finalDate, #memDate;
UPDATE players SET PlayerMembershipEndDate = #finalDate
WHERE players.PlayerID = pid;
SET result = 1;
END IF;
END
When I check the return value, it is 1, therefore the account does exist. It tells me the result of the select query is always that #finalDate is NULL.
However, if ake it out of the IF and just do:
SET #finalDate = DATE_ADD(DATE(NOW()), INTERVAL daysToAdd DAY);
The date is set correctly.
I'm not sire what I am doing wrong.
Thanks
Your procedure seems way too complicated. Perhaps this does what you want:
set #result = -1;
UPDATE players
SET PlayerMembershipEndDate = (case when (#result := 1) is null then NULL
when #memDate IS NULL OR DATE(#memDate) < DATE(NOW())
then DATE_ADD(DATE(NOW()), INTERVAL daysToAdd DAY)
else DATE_ADD(DATE(#memDate), INTERVAL daysToAdd DAY)
end)
WHERE players.PlayerID = pid;
The first condition in the case just sets #result if a row is found. I've left your formulation of DATE(NOW()) even though CURDATE() is more succinct.
I suspect the actual problem with your logic was the = NULL. This always returns "UNKNOWN", which is treated as false. The correct expression is is NULL.

MySQL - trigger on before insert + if data already exists + enum column

I am working on a trigger that I though is quite easy and should work but it is not working.
Here is the (abstract) table structure:
PK_id | FK1_id | FK2_id | status
1 | 12 | 15 | 'ok'
status column is defined as enum('ok', 'ok_2', 'not_ok') NUT NULL with no default value.
The trigger should verify that a combination of both FKx_id values already exists and if yes it should set the status to 'ok_2', otherwise to 'ok' and if the status is set in the INSERT INTO it is not touched.
The trigger I have right now (only body!):
BEGIN
DECLARE cnt INT;
SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id);
IF cnt > 0 AND NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok';
END IF;
END
Unfortunately this trigger sets the status always to 'ok' - please notice that the status is not part of the INSERT query (thus considered as NULL). I have previously tried this trigger body with the same result:
BEGIN
IF (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id) > 0 AND NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok';
END IF;
END
and also this (with the very same result):
BEGIN
IF EXISTS(SELECT * FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id LIMIT 1) AND NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok';
END IF;
END
Can anyone tell me why the first condition is never met even if I am inserting the same FKx_id combination that is already present in the table?
EDIT: I switched the condition and the result is also the same - no 'ok_2' status set:
BEGIN
DECLARE cnt INT;
SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id);
IF cnt = 0 AND NEW.status IS NULL THEN
SET NEW.status = 'ok';
ELSEIF NEW.status IS NULL THEN
SET NEW.status = 'ok_2';
END IF;
END
Got it.
The problem was this declaration of the status column:
status enum('ok', 'ok_2', 'not_ok') NOT NULL
which leads into status being pre-filled with the first enum's value if the status is not set in the INSERT statement. So the solution is next trigger body:
BEGIN
DECLARE cnt INT;
SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id);
IF cnt = 0 THEN
SET NEW.status = 'ok';
ELSEIF NEW.status = 'ok' THEN
SET NEW.status = 'ok_2';
END IF;
END
Now if I do this insert for the first time
INSERT INTO table (FK_1, FK_2) VALUES (100, 150)
the status is 'ok', if I insert this for the second time
INSERT INTO table (FK_1, FK_2) VALUES (100, 150)
the status is 'ok_2' and if I set the status explicitly like this:
INSERT INTO table (FK_1, FK_2, status) VALUES (100, 150, 'not_ok')
the status is 'not_ok'.
so, when working with enums that have no default value while are set as NOT NULL - do not expect them to be NULL on insert when omitted. The will be pre-filled probably with the first enums's value.

Mysql Function returning same value

I am in need of mysql function but gives same value every time
this mysql function gives me same value every time i.e. S_Start_ToBeStarted (Value of 1st If)
-- colorA
DELIMITER $$
DROP FUNCTION IF EXISTS `colorA`$$
CREATE FUNCTION `colorA`(
Appf VARCHAR(3),
Start_Datef DATETIME,
PDCf DATETIME
) RETURNS INT
DETERMINISTIC
BEGIN
DECLARE finalcolor INT DEFAULT 0;
IF Appf = 'Yes' & IFNULL(Start_Datef, 'NULL' = 'NULL' & sysdate() <= PDCf
THEN SET finalcolor = (SELECT `PP_Colors`.`S_Start_ToBeStarted` FROM `SCR_Sap`.`PP_Colors` LIMIT 1);
ELSE IF Appf = 'Yes' & IFNULL(Start_Datef, 'NULL') = 'NULL' & sysdate() > PDCf
THEN SET finalcolor = (SELECT `PP_Colors`.`S_Start_Error` FROM `SCR_Sap`.`PP_Colors` LIMIT 1);
ELSE IF Appf = 'Yes' & IFNULL(Start_Datef, 'NULL') != 'NULL' & sysdate() <= PDCf
THEN SET finalcolor = (SELECT `PP_Colors`.`S_Start_Ok` FROM `SCR_Sap`.`PP_Colors` LIMIT 1);
ELSE IF Appf = 'Yes' & IFNULL(Start_Datef, 'NULL') != 'NULL' & sysdate() > PDCf
THEN SET finalcolor = (SELECT `PP_Colors`.`S_Start_LateStarted` FROM `SCR_Sap`.`PP_Colors` LIMIT 1);
ELSE SET finalcolor = (SELECT `PP_Colors`.`S_NotApplicable` FROM `SCR_Sap`.`PP_Colors` LIMIT 1);
END IF;
END IF;
END IF;
END IF;
RETURN finalcolor;
END$$
DELIMITER ;
Null doesn't work well with = and != operators, the result of foobar=NULL is NULL (unknown) not true or false. Use IS NULL and IS NOT NULL instead