How can I cancel insertion inside the trigger? - mysql

Inside the History table, The COL1 shouldn't be like COL2, If was equal then cancel the insertion.
How can I do it?

For MySQL 5.7 use
CREATE TRIGGER prevent_self_referencing
BEFORE INSERT
ON tablename
FOR EACH ROW
BEGIN
IF NEW.column1 = NEW.column2 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Self-referencing not allowed.';
END IF;
END
And the same trigger for BEFORE UPDATE.
In shown window insert only 3 code lines, the whole IF statement.

Related

How to control column totals in mySQL using trigger?

I want to use Trigger in Mysql to be able to control "evaluation_weight" column in "evaluation_criteria" table. If the sum of the "evaluation_weight" column >= 100 after update/insert, it will not be possible to update/insert the newly entered value.
Here is the picture of "evaluation_criteria" table
You would need two triggers with one for update and another one for insert.
delimiter //
drop trigger if exists check_evaluation_insert ;
create trigger check_evaluation_insert before insert on evaluation_criteria for each row
begin
if (select ifnull(sum(evaluation_weight),0) from evaluation_criteria) + new.evaluation_weight>= 100 then
signal SQLSTATE VALUE '99999' SET MESSAGE_TEXT = 'The limit of evaluation_weight has been reached. INSERT fails. ';
end if;
end//
drop trigger if exists check_evaluation_update ;
create trigger check_evaluation_update before update on evaluation_criteria for each row
begin
if (select ifnull(sum(evaluation_weight),0) from evaluation_criteria) + new.evaluation_weight - old.evaluation_weight>= 100 then
signal SQLSTATE VALUE '99999' SET MESSAGE_TEXT = 'The limit of evaluation_weight has been reached. UPDATE fails. ';
end if;
end//
delimiter ;

SIGNAL SQLSTATE '45000' Doesn't stop Insert

I am having problems implementing a trigger into my table. I am using MySQL, Phpmyadmin
Scenario: Table User(user_id, name, surname, date_of_joining), record(record_id, date_of_record, weight, height, id_user)
a user can have multiple records which show his weight and height at a certain date. id_user is a foreign key referencing to user_id.
I am trying to implement a trigger for insert and update which checks if date_of_record is greater than date_of_joining, if not, the insert should be stopped.
This is a trigger I tried and the insert still goes through
CREATE TRIGGER date_check_insert BEFORE INSERT ON record
FOR EACH ROW
BEGIN
DECLARE date_of_registering DATE;
SET date_of_registering = (SELECT date_of_registering FROM user WHERE user_id = new.id_user);
IF (new.date_of_record NOT BETWEEN date_of_registering AND CURDATE()) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "Can not insert that value";
END IF;
END
Any help is appreciated
I'd slightly change the trigger:
Use session variable (so no DECLARE needed)
Put comparison logic in a single place in the WHERE clause (easier to read & understand)
Shows reason in error message
Use SELECT INTO variable instead of SET variable = query (not necessary, I just prefer this way)
So:
CREATE TRIGGER date_check_insert BEFORE INSERT ON record
FOR EACH ROW
BEGIN
SET #found = NULL;
SELECT
user_id INTO #found
FROM
user
WHERE
user_id = NEW.id_user
AND NEW.date_of_record BETWEEN date_of_registering AND NOW() -- or CURDATE() depend on your datetype
;
IF #found IS NULL THEN
SET #msg = CONCAT('Can not insert. Out of range value ', NEW.date_of_record);
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = #msg;
END IF;
END

How to make the trigger which controller the insert by checking condition inside JSON object

I want to create the trigger which will control the data insertion having age greater than 100 inside the JSON_object.
My trigger creating code
CREATE DEFINER=`root`#`localhost` TRIGGER `avoid_larage_age`
BEFORE INSERT ON `json_data`
FOR EACH ROW
SET #x INT;
x = JSON_EXTRACT(NEW.json_column, '$.age')
IF x > 100
THEN SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Warning: Age is two high';
END IF;
My expected output.
You can try the following code to control the data insertion.
DROP TRIGGER IF EXISTS `avoid`;
CREATE DEFINER=`root`#`localhost` TRIGGER `avoid`
BEFORE INSERT ON `json_data`
FOR EACH ROW
IF JSON_EXTRACT(NEW.json_column, '$.age') > 5
THEN SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Warning: Age is two high';
END IF

Can MySQL TRIGGER check all INSERT values separetly?

I've got simple database with tables: Sklep(SklepNazwa,Adres), Towar(TowarNazwa,Producent), Sprzedaz(SklepNazwa,SklepAdres,TowarNazwa,TowarProducent,Cena,Data)
I had to create TRIGGER like shown below.
Problem is that it don't work when I try to INSERT several rows at once. When at least one row triggers SIGNAL all values are dumped. Nothing gets inserted, even when it is ok to be inserted.
Can I somehow call
INSERT INTO Sprzedaz
VALUES (...),(...),(...),(...);
where some values are ok to be inserted and some should fail and show SIGNAL message?
DELIMITER $$
CREATE TRIGGER SprzedazInsert
BEFORE INSERT ON `Sprzedaz`
FOR EACH ROW
BEGIN
IF (SELECT COUNT(1) FROM Sprzedaz
WHERE NEW.SklepNazwa = Sprzedaz.SklepNazwa
AND NEW.SklepAdres = Sprzedaz.SklepAdres
AND NEW.TowarNazwa = Sprzedaz.TowarNazwa
AND NEW.TowarProducent = Sprzedaz.TowarProducent
AND NEW.Cena = Sprzedaz.Cena
AND NEW.`Data` = Sprzedaz.`Data`) > 0
THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'INSERT FAILED: Row already exists.';
ELSE
IF (SELECT COUNT(1) FROM Sklep WHERE NEW.SklepNazwa = Sklep.SklepNazwa) > 0
THEN
IF (NEW.SklepAdres != (SELECT Adres FROM Sklep WHERE NEW.SklepNazwa = Sklep.SklepNazwa))
THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'INSERT FAILED: Wrong "Sklep" data.';
END IF;
ELSE
INSERT INTO `Sklep` (`SklepNazwa`,`Adres`)
VALUES (NEW.SklepNazwa,NEW.SklepAdres);
END IF;
IF (SELECT COUNT(1) FROM Towar WHERE NEW.TowarNazwa = Towar.TowarNazwa) > 0
THEN
IF (NEW.TowarProducent != (SELECT Producent FROM Towar WHERE NEW.TowarNazwa = Towar.TowarNazwa))
THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'INSERT FAILED: Wrong "Towar" data.';
END IF;
ELSE
INSERT INTO `Towar` (`TowarNazwa`,`Producent`)
VALUES (NEW.TowarNazwa,NEW.TowarProducent);
END IF;
END IF;
END$$
If you try to insert several rows in the same transaction, the dbms assumes you want all the inserts to succeed or fail as a group. If you want rows to succeed or fail individually, you need to commit after each insert.

How to trigger a RegEx condition on either of two columns in MySQL?

I have two columns (attributes) in a MySQL table, which a unique RegEx condition is to be applied on either of them via trigger. It means either column1 OR column2's condition suffices for the trigger to return 0.
In other words, how can I put OR between these columns?
I came up with this solution, but I'm not sure there is a better solution:
CREATE DEFINER = CURRENT_USER TRIGGER `MyDatabase`.`TableName_BEFORE_INSERT`
BEFORE INSERT ON `TableName` FOR EACH ROW
BEGIN
IF (NEW.column1,column2 REGEXP '^[augc]+' ) = 0 THEN
ROLLBACK;
SIGNAL SQLSTATE '12345'
SET MESSAGE_TEXT = 'Your Input can contain only the following letters 'AUGC'. Please correct your input format;
END IF;
END
DELIMITER;
There are a few problems with your solution, it doesn't even compile, because:
COMMIT and ROLLBACK are not allowed in triggers
This syntax is wrong: NEW.column1,column2 REGEXP ...
there is a syntax error at this place ...letters 'AUGC'. Please..., you need to use double aphostrophes ...letters ''AUGC''. Please...
Try this trigger instead:
CREATE TRIGGER `TableName_BEFORE_INSERT`
BEFORE INSERT ON `TableName` FOR EACH ROW
BEGIN
IF NEW.column1 REGEXP '^[augc]+' OR NEW.column2 REGEXP '^[augc]+' THEN
-- ROLLBACK;
SIGNAL SQLSTATE '12345'
SET MESSAGE_TEXT = 'Your Input can contain only the following letters ''AUGC''. Please correct your input format';
END IF;
END
/
Demo: http://sqlfiddle.com/#!9/27f5a