SQL Trigger chaining IF statements - mysql

I seem to be unable to have multiple, non-related if statements in SQL
I have a table of users with a bunch of columns that should be unique, but some are also optional. Since SQL throws an error when more than one fields have a NULL value, I decided to approach the problem with a trigger.
Here is how I wrote it:
create definer = root#localhost trigger `check-if-unique-update`
before UPDATE
on contact
for each row
if new.phone2 is null
then
if (select count(id) from contact where phone2 = new.phone2 or phone = new.phone2) > 0
then
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'There is something wrong with the Contact data you entered!';
end if;
end if;
if new.email2 is not null
then
if (select count(id) from contact where email2 = new.email2 or email = new.email2)
then
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'There is something wrong with the Contact data you entered!';
end if;
end if;
if new.fax is not null
then
end if;
end if;
First off, DataGrip (DataBase management IDE by JetBrains) gives me an error. When I then upload the file to the MySql DataBase it only shows the first if Statement
if new.phone2 is null
then
if (select count(id) from contact where phone2 = new.phone2 or phone = new.phone2) > 0
then
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'There is something wrong with the Contact data you entered!';
end if;
end if;
I feel like I am missing some rudimentary detail, or is this just not possible in sql?

Have you tried including a begin-end in your trigger?
create definer = root#localhost trigger `check-if-unique-update`
before UPDATE
on contact
for each row
begin
if new.phone2 is null
then
if (select count(id) from contact where phone2 = new.phone2 or phone = new.phone2) > 0
then
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'There is something wrong with the Contact data you entered!';
end if;
end if;
if new.email2 is not null
then
if (select count(id) from contact where email2 = new.email2 or email = new.email2)
then
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'There is something wrong with the Contact data you entered!';
end if;
end if;
if new.fax is not null
then
end if;
end if;
end
Depending on your IDE, you may need to change the delimiter to // for example.
For reference see: https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html

Related

How to compare a parameter of a Stored procedure with a REGEXP

I have a stored Procedure that I want to use for validations in the tables, and I have a regexp that I need to compare one of the parameters, how can I compare the regexp with my parameter. I tried this:
SELECT id REGEXP '^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$'
id is the parameter that I receive, this is all the stored procedure:
DELIMITER &&
CREATE PROCEDURE ValidationSalaryChange(
IN changeDate DATE,
IN id VARCHAR(11)
))
BEGIN
IF NOT (SELECT id REGEXP '^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$') THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'error';
ELSE IF (changeDate > NOW()) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'error';
END IF;
END &&
DELIMITER ;
You don't need to use the subquery.
You have an extra ) after the parameter list.
ELSE IF needs to be one word ELSEIF.
DELIMITER &&
CREATE PROCEDURE ValidationSalaryChange(
IN changeDate DATE,
IN id VARCHAR(11)
)
BEGIN
IF id NOT REGEXP '^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'error in id';
ELSEIF changeDate > NOW() THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'error in changeDate';
END IF;
END &&
DELIMITER ;

MYSQL IF do nothing ELSE

I have a table users. When someone one to a insert new record which contains in name or in surname character diffrent from a-z,A-Z or space it will be a mistake and error occur. The code fails because after first THEN should be something, but i dont know what to put insidee. Because I only want to execute insert when if statement is true.
delimiter //
CREATE TRIGGER check_name_surname
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
IF NEW.name REGEXP '^[a-zA-Z' '.]+$' and NEW.surname REGEXP '^[a-zA-Z' '.]+$' then
ELSE
SIGNAL SQLSTATE VALUE '45000' SET MESSAGE_TEXT = 'Incorrect name and surname';
END IF;
END;//
delimiter;
When you have nothing to put in your IF statement then you have to 'negate' the else condition and put it in the if.
So here you will throw an error IF name is not alphanumeric OR surname is not alphanumeric.
IF NEW.name NOT REGEXP '^[a-zA-Z' '.]+$' OR NEW.surname NOT REGEXP '^[a-zA-Z' '.]+$' THEN
SIGNAL SQLSTATE VALUE '45000' SET MESSAGE_TEXT = 'Incorrect name and surname';
END IF;
Do not forget that the AND operator become OR.

Issue handling with MySQL trigger

This is my trigger for show error handling :
DELIMITER //
CREATE TRIGGER NOTA_PENJUALAN_INS BEFORE INSERT ON nota_penjualan FOR EACH ROW
BEGIN
DECLARE VDATE DATETIME;
If (NEW.INVENTORY_OUT_ID IS NOT NULL) then
CALL STATUS_INV_OUT(NEW.INVENTORY_OUT_ID);
SELECT (a.DOCUMENT_DATE) INTO VDATE
FROM inventory_out a
INNER JOIN NOTA_PENJUALAN b ON a.INVENTORY_OUT_ID=b.INVENTORY_OUT_ID
WHERE b.NOTA_PENJUALAN_ID=NEW.NOTA_PENJUALAN_ID;
End IF;
IF(VDATE > NEW.DOCUMENT_DATE) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'sorry can not exceed the date that has been specified';
END IF;
END
//
It displays:
And does not display my ShowMessage.

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.

SQL duplicate trigger

I have simple project for database classes there i have shop database which implement such logic: for each customer in order table we have order with type = 'CART' when customer confirm his order his order change it type to 'ORDER' and we create a new CART for our customer.
Now i want to write trigger that allows me to control that each customer has only one CART.
I write something like this
DELIMITER $$
USE `newshop`$$
CREATE
DEFINER=`root`#`localhost`
TRIGGER `newshop`.`cart_check`
BEFORE INSERT ON `newshop`.`order`
FOR EACH ROW
BEGIN
DECLARE msg VARCHAR(255);
DECLARE count_pn INTEGER;
SELECT count(*) INTO count_pn FROM newshop.order
where newshop.order.type = NEW.type
and NEW.user_id = newshop.order.user_id
and NEW.type = 'CART'
or NEW.type = 'cart'
LIMIT 1;
if count_pn > 0 THEN
BEGIN
set msg = 'Oh no';
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
end;
ELSE
BEGIN
set msg = 'Oh yeah';
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
END;
END IF;
END$$
then when i try to insert into table new order with type cart for user with id = 1, that already has a cart - this trigger doesn't allow me to do this and if i try to add a cart for another user, that doesn't have cart - this trigger also doesn't allow me to do this.
In else, you also have the SIGNAL SQLSTATE=45000, which is unhandled exception, it will cause return as failed.
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;