delete trigger when condition is met - mysql

I know it is a simple question but i am not finding the answer anywhere.
That's my table:
city | CREATE TABLE `city` (
`ID` int(11) NOT NULL,
`Name` char(35) NOT NULL DEFAULT '',
`CountryCode` char(3) NOT NULL DEFAULT '',
`District` char(20) NOT NULL DEFAULT '',
`Population` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `FKcode99` (`CountryCode`),
CONSTRAINT `FKcode99` FOREIGN KEY (`CountryCode`) REFERENCES `country` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
The question is: If you want to delete a city, the population must be 275,000 or less.
I tried
ALTER TABLE `world`.`city`
RENAME TO `world`.`DeleteCity` ;
USE `world`;
DELIMITER $$
DROP TRIGGER IF EXISTS world.DeleteCity_ADEL$$
USE `world`$$
CREATE TRIGGER `DeleteCity_ADEL` AFTER DELETE ON `DeleteCity` FOR EACH ROW
IF (OLD.population <= 275000) THEN
DELETE FROM city WHERE NEW.name=OLD.name;
END IF;
$$
DELIMITER ;
but it doesn't work. Can anybody help me?

I would do it in this way:
CREATE TRIGGER `DeleteCity_ADEL` BEFORE DELETE ON `DeleteCity` FOR EACH ROW
IF (OLD.population > 275000) THEN
SIGNAL SQLSTATE '45123'
SET MESSAGE_TEXT = 'If you want to delete a city, the population must be 275,000 or less.';
END IF;
/
This trigger raises an error when somone is trying to delete a record with population > 275,000 and returns a clear explanation (error message) to him.
If population is less or equal than 275,000, the record is silently deleted.

Related

Why are these triggers not detecting wrong data although the syntax should be correct?

I want to add two triggers to my mysql database, but it seems that both triggers are not working (although the mysql compiler accepts the syntax). I do not receive an error message when I insert new data rows that should be detected as wrong by the trigger. Do you know what the mistake could be?
Here is the code of the triggers:
USE `mydb`$$
DROP TRIGGER IF EXISTS `mydb`.`Teilnehmer_BEFORE_INSERT` $$
USE `mydb`$$
CREATE DEFINER = CURRENT_USER TRIGGER `mydb`.`Teilnehmer_BEFORE_INSERT` BEFORE INSERT ON `Teilnehmer` FOR EACH ROW
BEGIN
IF (DATEDIFF(CURRENT_DATE(),NEW.Geburtsdatum) < 6570) THEN
-- Throw Exception
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Age is less than 18 years!';
END IF; -- A semicolon (delimiter) is missing here
END
$$
DELIMITER ;
DELIMITER $$
CREATE TRIGGER `enforce_phone_check` BEFORE INSERT ON `Teilnehmer` FOR EACH ROW
BEGIN
IF (NEW.Telefonnummer REGEXP '^(\\+?[0-9]{1,4}-)?[0-9]{3,10}$' ) = 0 THEN
SIGNAL SQLSTATE '33455'
SET MESSAGE_TEXT = 'Your Phone Number is incorrect';
END IF;
END$$
DELIMITER ;
Here are the table definitions:
CREATE TABLE IF NOT EXISTS `mydb`.`Preis` (
`idPreis` INT NOT NULL,
`Menge` VARCHAR(45) NULL,
`Wert` INT NULL,
`Art` VARCHAR(45) NULL,
PRIMARY KEY (`idPreis`))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `mydb`.`Teilnehmer` (
`idTeilnehmer` INT NOT NULL,
`email` VARCHAR(45) NULL,
`Preis_idPreis` INT NOT NULL,
`Vorname` VARCHAR(45) NULL,
`Nachname` VARCHAR(45) NULL,
`Strasse` VARCHAR(45) NULL,
`Hausnr.` VARCHAR(45) NULL,
`PLZ` INT(4) NULL,
`Ort` VARCHAR(64) NULL,
`Geburtsdatum` DATE NULL,
`Telefonnummer` VARCHAR(16) NULL,
`Bild_URL TEXT` TEXT(500) NULL,
`ts` timestamp,
PRIMARY KEY (`idTeilnehmer`, `Preis_idPreis`),
INDEX `fk_Teilnehmer_Preis1_idx` (`Preis_idPreis` ASC) VISIBLE,
CONSTRAINT `fk_Teilnehmer_Preis1`
FOREIGN KEY (`Preis_idPreis`)
REFERENCES `mydb`.`Preis` (`idPreis`),
UNIQUE Key `idTeilnehmer`(`idTeilnehmer`, `Nachname`))
ENGINE = InnoDB;
And here is a table entry that should throw an error for both trigger (but doesn't):
INSERT INTO `mydb`.`teilnehmer` (`idTeilnehmer`, `email`, `Preis_idPreis`, `Vorname`, `Nachname`, `Strasse`, `Hausnr.`, `PLZ`, `Ort`, `Geburtsdatum`, `Telefonnummer`, `Bild_URL TEXT`, `ts`) VALUES ('1', 'sdfsdf', '1', 'sdfsd', 'sdfsd', 'sdfsdf', '17', '9230', 'Flawil', '2005-06-06', '2342345', 'stsdfsdf', '2019-06-06');

Update Column in Another Table Based off INT value Change using MySQL AFTER UPDATE Trigger

Getting error after error. Basically I am trying to set a columns value to 1 in my products table automatically if upon update of the product_stock table the column available is greater than 0 (meaning, at least one in stock).
MPN is both a unique and foreign key in my products table, so as long a positive value in the column available in the table product_stock the in_stock value for the mpn in the products table should be set to 1.
Two tables I'm working with:
1
CREATE TABLE `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`mpn` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`in_stock` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `mpn` (`mpn`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
2
CREATE TABLE `product_stock` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`mpn` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`size` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`available` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `product_stock_ibfk_1` (`mpn`),
CONSTRAINT `product_stock_ibfk_1` FOREIGN KEY (`mpn`) REFERENCES `products` (`mpn`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
And one variation of my trigger
DELIMITER $$
CREATE TRIGGER ps_update AFTER UPDATE ON `product_stock`
FOR EACH ROW BEGIN
IF NEW.available > 0 THEN
SET products.in_stock = 1;
ELSE
SET products.in_stock = 0;
END IF;
END$$
DELIMITER ;
Error code
1193 - Unknown system variable 'in_stock'
You cannot update value in another table using SET alone. You need to use proper UPDATE statement to do so.
I have also added more conditions, so that it does not fire UPDATE query every time. It will fire UPDATE only when there is a change in the in_stock value required.
DELIMITER $$
CREATE TRIGGER ps_update AFTER UPDATE ON `product_stock`
FOR EACH ROW BEGIN
-- update only when there is a change in the available
IF NEW.available <> OLD.available THEN
-- update only when item becomes in_stock
IF NEW.available > 0 AND OLD.available <= 0 THEN
UPDATE products
SET products.in_stock = 1
WHERE products.mpn = NEW.mpn;
-- update only when item becomes out_stock
ELSEIF NEW.available <= 0 AND OLD.available > 0 THEN
UPDATE products
SET products.in_stock = 0
WHERE products.mpn = NEW.mpn;
END IF;
END IF;
END $$
DELIMITER ;

replace does only trigger one trigger in mariadb

I have the following tables
CREATE TABLE `trigger_root` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`p` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `trigger_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`p` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
and the following triggers
DELIMITER ||
CREATE TRIGGER tit
BEFORE INSERT ON trigger_root
FOR EACH ROW
BEGIN
INSERT INTO trigger_test (p) values (NEW.p);
END ||
CREATE TRIGGER tdt
BEFORE delete ON trigger_root
FOR EACH ROW
BEGIN
delete from trigger_test where p=OLD.p;
END ||
DELIMITER ;
However if I use the following statement
replace into trigger_root(id,p) select id,p from trigger_root;
only the delete trigger is called. if i remove the delete trigger the insert trigger is called.
so it seems replace only triggers one but not both triggers
is that a general restriction or do I do something wrong?
I found the error. the insert nedds to be after rahter than before.

ERROR 1452 : Cannot add or update a child row: a foreign key constraint fails

Help me please!
I am having this error.
Error: Cannot add or update a child row: a foreign key constraint fails (world.alarmes, CONSTRAINT fk_alarmes_registos1 FOREIGN KEY (idRegisto) REFERENCES registos (idRegisto) ON DELETE NO ACTION ON UPDATE NO ACTION)
I have these tables.
CREATE TABLE `registos` (
`data_registo` char(10) NOT NULL,
`hora_registo` time NOT NULL,
`idSensor` varchar(8) NOT NULL,
`Temperatura` char(6) DEFAULT NULL,
`Humidade` char(6) DEFAULT NULL,
`pt_orvalho` char(6) DEFAULT NULL,
`idRegisto` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`idRegisto`,`idSensor`,`data_registo`,`hora_registo`),
KEY `fk_registos_sensores1_idx` (`idSensor`),
CONSTRAINT `fk_registos_sensores1` FOREIGN KEY (`idSensor`) REFERENCES `sensores` (`idSensor`) ON DELETE NO ACTION ON UPDATE NO ACTION
)
CREATE TABLE `alarmes` (
`idAlarme` int(11) NOT NULL AUTO_INCREMENT,
`descricao_alarme` varchar(45) DEFAULT NULL,
`data_criacao` datetime DEFAULT CURRENT_TIMESTAMP,
`idRegisto` int(11) NOT NULL DEFAULT ''0'',
PRIMARY KEY (`idAlarme`,`idRegisto`),
KEY `fk_alarmes_registos1_idx` (`idRegisto`),
CONSTRAINT `fk_alarmes_registos1` FOREIGN KEY (`idRegisto`) REFERENCES `registos` (`idRegisto`) ON DELETE NO ACTION ON UPDATE NO ACTION
)
When I do an insert into the table records the error pops up.
insert into registos values ('2014-03-31', '14:03:32', 'BrgTH032', '22.3', '45.3', '9.9', '32');
If I do this:
SET FOREIGN_KEY_CHECKS=0
the next insertion already accepted, but when I try again. back to give the same error.
I've been researching and fails because the registos table references a foreign key from the sensores table. You can't directly insert into a relational table without there being a corresponding entry in the table that is being referenced.
But I don't know how to resolve this.
Help me please.
-------EDIT( I used a trigger to populate the table Alarmes)------------------------
DELIMITER $$
create TRIGGER alerta
BEFORE INSERT ON registos
FOR EACH ROW
begin
Set #tempmax=0;
Set #tempmin=0;
select lim_inf_temp, lim_sup_temp into #tempmin, #tempmax from sensores where idSensor=NEW.idSensor;
Set #maxidAlarme=0;
if (CAST(NEW.Temperatura AS UNSIGNED)<#tempmin) then
SELECT MAX(idAlarme) into #maxidAlarme FROM alarmes;
SET #maxidAlarme=#maxidAlarme+1;
INSERT INTO alarmes(idAlarme,descricao_alarme, idRegisto) VALUES (#maxidAlarme,"temperatura inserida inferior ao normal",New.idRegisto);
end if;
if (CAST(NEW.Temperatura AS UNSIGNED)>#tempmax) then
SELECT MAX(idAlarme) into #maxidAlarme FROM alarmes;
SET #maxidAlarme=#maxidAlarme+1;
INSERT INTO alarmes(idAlarme,descricao_alarme, idRegisto) VALUES (#maxidAlarme,"temperatura inserida superior ao normal",New.idRegisto);
end if;
end $$;
DELIMITER ;
You are trying to insert more values into the table than allowed 7 (seven) but 6 (six) expected.
Please, always include the columns that you are inserting to in an 'insert' query.
There are seven columns in this table but one is an 'auto increment' column so there should be 6 (six) values in the insert query.
CREATE TABLE `registos` (
`data_registo` char(10) NOT NULL,
`hora_registo` time NOT NULL,
`idSensor` varchar(8) NOT NULL,
`Temperatura` char(6) DEFAULT NULL,
`Humidade` char(6) DEFAULT NULL,
`pt_orvalho` char(6) DEFAULT NULL,
`idRegisto` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`idRegisto`,`idSensor`,`data_registo`,`hora_registo`),
KEY `fk_registos_sensores1_idx` (`idSensor`),
CONSTRAINT `fk_registos_sensores1
Here is the 'insert' query:
insert into registos values ('2014-03-31', '14:03:32', 'BrgTH032', '22.3', '45.3', '9.9', '32');
There are seven values but you would expect the query to look like (columns added):
insert into registos (data_registo, hora_registo, idSensor, Temperatura, Humidade, pt_orvalho)
values ('2014-03-31', '14:03:32', 'BrgTH032', '22.3', '45.3', '9.9', '32');
I suggest that the query should be:
insert into registos (data_registo, hora_registo, idSensor, Temperatura, Humidade, pt_orvalho)
values ('2014-03-31', '14:03:32', 'BrgTH032', '22.3', '45.3', '9.9');
The trigger on 'registos' must be an after insert trigger to pick up the NEW 'idRegisto' value.
create TRIGGER alerta
AFTER INSERT ON registos
FOR EACH ROW
begin

How to Add integer column to an String column in MySQl 5.0

I Want to add an Integer Column to a String that's because i need to generate a varchar variable with a numeric part that automatically increments. For example, P000001,P000002...
In order to do that what i am doing while creation of table i have taken an int field ID which auto_increments and i am Concatenating P with 00000 and the ID value
The Table i have created is :
CREATE TABLE tblAcceptTest(
ID int AUTO_INCREMENT NOT NULL primary key,
PatientID as CONCAT('P' , CONCAT('000000',CAST(ID as char)))
);
It Shows me the error from as keyword.
Please help
MySQL's documentation (http://dev.mysql.com/doc/refman/5.1/en/create-table.html) says, "the default value must be a constant; it cannot be a function or an expression." Why don't you just get the PatientID value afterward as part of the SELECT:
SELECT CONCAT('P', LPAD(ID, 6, 0)) AS PatientID FROM tblAcceptTest;
It looks like you want six digits after the "P", so try this for your expression:
CONCAT('P', LPAD(ID, 6, '0'))
Mysql has little support for computed columns.
Patient ID from your specification could be a char(7)
CREATE TABLE tblAcceptTest(
ID int AUTO_INCREMENT NOT NULL primary key,
PatientID char(7)
);
Then create some triggers. Note that the following insert trigger will cause issues with high concurrency servers.
DELIMITER |
CREATE TRIGGER tblAcceptTest_insert BEFORE INSERT ON tblAcceptTest
FOR EACH ROW BEGIN
DECLARE next_id INT;
SET next_id = (SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='tblAcceptTest');
SET NEW.PatientID = CONCAT('P' , RIGHT(CONCAT('000000',next_id),6)) ;
END;
|
CREATE TRIGGER tblAcceptTest_update BEFORE UPDATE ON tblAcceptTest
FOR EACH ROW BEGIN
SET NEW.PatientID = CONCAT('P' , RIGHT(CONCAT('000000',NEW.ID),6)) ;
END;
|
DELIMITER ;
You use relationships and views to achieve the same result.
CREATE TABLE `patient` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`patient` varchar(60) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `accepted_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`patient_id` int(11) NOT NULL,
`accepted` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `patient_id` (`patient_id`),
CONSTRAINT `accepted_test_ibfk_1` FOREIGN KEY (`patient_id`) REFERENCES `patient` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
create or replace view accepted_test_veiw as
select CONCAT('P' , RIGHT(CONCAT('000000',patient_id),6)) patient_key
, accepted
, id accepted_test_id
, patient_id
from accepted_test ;
select * from `accepted_test_veiw`