SQL Trigger After Update not working - mysql

please help me...
USE `arma3life`;
DELIMITER $$
CREATE DEFINER=`zoxxen`#`localhost` TRIGGER `money_log` AFTER UPDATE ON `players` FOR EACH ROW
BEGIN
IF NEW.`bankacc` <> OLD.`bankacc` OR NEW.`cash` <> OLD.`cash` THEN
INSERT INTO `supportertool_money` (
`i_player_id`
,`i_bankacc`
,`i_cash`
,`dt_inserted`
)
VALUES (
NEW.`playerid`
,NEW.`bankacc`
,NEW.`cash`
,NOW()
);
END IF;
END $$
DELIMITER ;
There have to be a issue.. I cant Update my rows anymore and the Trigger is not working
I'm using innodb

Your if statement is:
IF NEW.`bankacc` <> OLD.`bankacc` OR NEW.`cash` <> OLD.`cash` THEN
The conditions do not do what you expect when values are NULL. Try this:
IF NEW.bankacc <> OLD.bankacc OR
NEW.bankacc is null and OLD.bankacc is not null or
NEW.bankacc is not null and OLD.bankacc is null or
NEW.cash <> OLD.`cash` or
NEW.cash is null and OLD.cash is not null or
NEW.cash is not null and OLD.cash is null then

Related

How to check NEW value exists in BEFORE UPDATE Trigger Mysql

I have table Demo:
create table Demo (
id int(10) auto_increment primary key,
text varchar(30) default null,
istrue boolean default false
);
I want create a update trigger such that:
When Update Demo set istrue = false where id = 1; (not "set text = ") -> normal update.
When Update Demo set text= 'abc' where id = 1; ("set text = ") -> SET NEW.text := concat(OLD.text,'#', NEW.text);
I have implemented trigger as follows:
DELIMITER $$
CREATE TRIGGER update_text
BEFORE update ON Demo
FOR EACH ROW
BEGIN
IF (exists(SELECT NEW.text)) THEN -- how to check NEW.text exists???
SET NEW.text := concat(OLD.text,'#', NEW.text);
END IF;
END$$
DELIMITER ;
But it isn't working! Please help. Thank You!!! (My English is not good. Hope everyone sympathized)
CREATE TRIGGER update_text
BEFORE update
ON Demo
FOR EACH ROW
SET NEW.text = CASE WHEN OLD.text <=> NEW.text
THEN NEW.text
ELSE CONCAT(OLD.text, '#', NEW.text)
END;
PS. Single-statement trigger - BEGIN-END and DELIMITER reassing not needed.
After the deep investigation I have found the way to detect that the field value was set in UPDATE statement.
However, I can't guarantee its reliability. I only check does the substring '`text`' is present in current query text - but there is a lot of situations when this check will give errorneous result, for example, wrong TRUE if this substring is a part of new value, or wrong FALSE if the fieldname is not wrapped with backticks. So be aware.
CREATE TRIGGER update_text
BEFORE update
ON demo
FOR EACH ROW
SET NEW.`text` = CASE WHEN LOCATE('`text`', ( SELECT info
FROM information_schema.processlist
WHERE id = CONNECTION_ID()
)
)
THEN CONCAT(OLD.`text`, '#', NEW.`text`)
ELSE NEW.`text`
END;
fiddle

mysql trigger on update: how to detect NULL values?

I try to update the porcentageComplete profil when users updates his profile:
statut field:
`statut` enum('Marié','En couple','Divorcé') DEFAULT NULL,
Trigger is:
DROP TRIGGER IF EXISTS update_user;
DELIMITER $$
CREATE TRIGGER update_user
BEFORE UPDATE
ON users FOR EACH ROW
BEGIN
DECLARE porcentage int default 0;
IF NEW.statut!=NULL OR OLD.statut!=NULL THEN
set porcentage = porcentage + 1;
END IF;
SET NEW.porcentageCompleted = porcentage;
END$$
This not update correctly the porcentageCompleted : it looks like NULL comparaison does not work correctly
Comparisons with = or <>(or !=) to a NULL value yield NULL themselves, so not true, i.e. false. Use IS NULL and IS NOT NULL to check for NULLs.
...
IF NEW.statut IS NOT NULL
OR OLD.statut IS NOT NULL THEN
...
Worth a read: 3.3.4.6 Working with NULL Values

How to get column's DEFAULT in trigger?

I'd like one column's value to be forced to DEFAULT in trigger by some conditions.
In example below, if b IS NULL, a should be set with defined DEFAULT (that is 'SYSTEM').
CREATE TABLE `t_default` (
`n` VARCHAR(50) NOT NULL
, `a` VARCHAR(50) NOT NULL DEFAULT 'SYSTEM'
, `b` VARCHAR(50) NULL DEFAULT NULL
-- To moderators: please do not edit my formatting :)
);
DELIMITER //
CREATE TRIGGER `TRG_t_default_BeforeInsert` BEFORE INSERT ON `t_default` FOR EACH ROW BEGIN
IF NEW.b IS NULL THEN
SET NEW.a = DEFAULT(a);
END IF;
END
//
DELIMITER ;
Unfortunately, this gives error message "Unknown column 'a' in 'field list'" on insert:
INSERT INTO t_default (n) VALUES ('1');
I've found similar question, however providing table name or db + table name does not work as well:
CREATE TRIGGER `TRG_t_default_BeforeInsert` BEFORE INSERT ON `t_default` FOR EACH ROW BEGIN
IF NEW.b IS NULL THEN
SET NEW.a = DEFAULT(t_default.a);
-- SET NEW.a = DEFAULT(test.t_default.a);
END IF;
END
In this case message is slightly different: "Unknown table 't_default' in field list"
Also, I tried to use back quotes around column name with no success.
So, is it possible to get column DEFAULT in trigger at all? I'm using MySQL 5.7.
Thanks.
P.S. Sure, I know that I can do SET NEW.a = 'SYSTEM';
You can try
IF NEW.b IS NULL THEN
SELECT COLUMN_DEFAULT INTO #def FROM information_schema.COLUMNS
WHERE table_schema = 'database_name'
AND table_name = 't_default'
AND column_name = 'a';
SET NEW.a = #def;
END IF;

Question about Update on Trigger with condition

I can't find the correct syntax for the trigger I tried to code.
I want to update a timestamp every time there is an update on the table but only for specific rows. I want to update the "UPDATE_TIME" only for the last "N_TACHE"
I can't find how to use SET with a where clause.
CREATE TRIGGER "time_on_update"
BEFORE UPDATE ON "SAVE_UPDATE"
FOR EACH ROW
BEGIN
IF
(NEW.DATE_DE_RDV <> OLD.DATE_DE_RDV)
OR
(NEW.ADRESSE <> OLD.ADRESSE)
OR
(NEW.CODE_POSTAL <> OLD.CODE_POSTAL)
OR
(NEW.VILLE <> OLD.VILLE)
THEN
SET (NEW.UPDATE_TIME = current_timestamp WHERE N_TACHE= (SELECT MAX(N_TACHE));
END IF;
If you have any suggestion I take it.
Thanks in advance
EDIT :
This one is working but it update all the rows and I just want to update "update_time" for the last value of "N_TACHE" when "RDV","ADRESSE","CODE_POSTAL" or "VILLE" is updated
DELIMITER $$
CREATE TRIGGER `time_on_update`
BEFORE UPDATE ON `SAVE_UPDATE`
FOR EACH ROW
BEGIN
IF
(SELECT MAX(N_TACHE)
FROM SAVE_UPDATE
WHERE
((NEW.DATE_DE_RDV <> OLD.DATE_DE_RDV)
OR
(NEW.ADRESSE <> OLD.ADRESSE)
OR
(NEW.CODE_POSTAL <> OLD.CODE_POSTAL)
OR
(NEW.VILLE <> OLD.VILLE)))
THEN
SET NEW.UPDATE_TIME = current_timestamp;
END IF;
END
$$
DELIMITER ;

Why opposite operation <> doesn't work on trigger?

I have a trigger which is AFTER UPDATE. I have a condition in that which doesn't work, How can I fix it?
$$
BEGIN
IF NEW.colname <> OLD.colname THEN
DELETE FROM tableX WHERE id = OLD.id;
END IF;
END
$$
It should be noted if I write this IF 1 THEN then that DELETE query works. So the problem is that condition. What's wrong with it?
As #Darwin von Corax said in the comments, when one of these NEW.colname, OLD.colname is null, then all of that condition returns false. So I want to know how can I create a condition which acts like this ?
Null <> 10 -- true
Null <> Null -- false
10 <> 12 -- true
32 <> Null -- true
3 <> 3 -- false
If either NEW.colname or OLD.colname is null, then <> will return null which if would treat the same as false.
Fortunately, there is a solution: the <=> (NULL-safe equality) operator, which returns 1 if both operands are null and 0 if only one is. The expression
IF NOT (NEW.colname <=> OLD.colname) THEN
should do what you need.
Just add logic for checking null conditions. It is not triggered when both columns are null which means that no changes happen.
$$
BEGIN
IF
-- when exactly one of the column is null
NEW.colname is not null and OLD.colname is null or
NEW.colname is null and OLD.colname is not null or
-- when both are not null compare their values
NEW.colname is not null and OLD.colname is not null and NEW.colname <> OLD.colname THEN
DELETE FROM tableX WHERE id = OLD.id;
END IF;
END
$$