MYSQL Insert values from another table - trigger - mysql

I have these tables in my database:
I want to add the registod and alarmes table one idRegisto .
The alarm table is populated automatically by a trigger. I would like to connect the two tables and the table alarmes populated idRegistos automatically by a trigger with the values โ€‹โ€‹of table records.
Does anyone can help me please.
I hope I have explained well my doubts
Thank you
My Trigger that populated table alarmes
DELIMITER $$
create TRIGGER alerta
BEFORE INSERT ON registos
FOR EACH ROW
begin
Set #comp=0;
Set #tempmax=0;
Set #tempmin=0;
Set #hummax=0;
Set #hummin=0;
Set #orvalho=0;
select lim_inf_temp, lim_sup_temp, lim_sup_humid, lim_inf_humid, lim_pt_orvalho into #tempmin, #tempmax, #hummax, #hummin, #orvalho 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) VALUES (#maxidAlarme,"ERROR");
end if;
end $$;
DELIMITER ;

In alarm table, do you want to use the same newly generated idRegisto of registos table? - Ravinder
Yes. This is what i want. โ€“ user3320956
To insert the same newly generated idRegisto field value in alarm table,
Change part of your trigger body as below:
if ( CAST( NEW.Temperatura AS UNSIGNED ) < #tempmin ) then
SELECT MAX( idAlarme ) into #maxidAlarme FROM alarmes;
SET #maxidAlarme := #maxidAlarme + 1;
SET #auto_idRegisto := ( SELECT AUTO_INCREMENT
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'registos'
AND TABLE_SCHEMA = DATABASE() );
INSERT INTO alarmes( idAlarme, descricao_alarme, idRegisto )
VALUES ( #maxidAlarme, "ERROR", #auto_idRegisto );
end if;

Related

update a table after inserting a value in the same table using triggers [duplicate]

I am running a MySQL Query. But when a new row is added from form input I get this error:
Error: Can't update table 'brandnames' in stored function/trigger because it is
already used by statement which invoked this stored function/trigger.
From the code:
CREATE TRIGGER `capital` AFTER INSERT ON `brandnames`
FOR EACH
ROW UPDATE brandnames
SET bname = CONCAT( UCASE( LEFT( bname, 1 ) ) , LCASE( SUBSTRING( bname, 2 ) ) )
What does this error mean?
You cannot change a table while the INSERT trigger is firing. The INSERT might do some locking which could result in a deadlock. Also, updating the table from a trigger would then cause the same trigger to fire again in an infinite recursive loop. Both of these reasons are why MySQL prevents you from doing this.
However, depending on what you're trying to achieve, you can access the new values by using NEW.fieldname or even the old values --if doing an UPDATE-- with OLD.
If you had a row named full_brand_name and you wanted to use the first two letters as a short name in the field small_name you could use:
CREATE TRIGGER `capital` BEFORE INSERT ON `brandnames`
FOR EACH ROW BEGIN
SET NEW.short_name = CONCAT(UCASE(LEFT(NEW.full_name,1)) , LCASE(SUBSTRING(NEW.full_name,2)))
END
The correct syntax is:
FOR EACH ROW SET NEW.bname = CONCAT( UCASE( LEFT( NEW.bname, 1 ) )
, LCASE( SUBSTRING( NEW.bname, 2 ) ) )
A "BEFORE-INSERT"-trigger is the only way to realize same-table updates on an insert, and is only possible from MySQL 5.5+. However, the value of an auto-increment field is only available to an "AFTER-INSERT" trigger - it defaults to 0 in the BEFORE-case. Therefore the following example code which would set a previously-calculated surrogate key value based on the auto-increment value id will compile, but not actually work since NEW.id will always be 0:
create table products(id int not null auto_increment, surrogatekey varchar(10), description text);
create trigger trgProductSurrogatekey before insert on product
for each row set NEW.surrogatekey =
(select surrogatekey from surrogatekeys where id = NEW.id);
#gerrit_hoekstra wrote: "However, the value of an auto-increment field is only available to an "AFTER-INSERT" trigger - it defaults to 0 in the BEFORE-case."
That is correct but you can select the auto-increment field value that will be inserted by the subsequent INSERT quite easily. This is an example that works:
CREATE DEFINER = CURRENT_USER TRIGGER `lgffin`.`variable_BEFORE_INSERT` BEFORE INSERT
ON `variable` FOR EACH ROW
BEGIN
SET NEW.prefixed_id = CONCAT(NEW.fixed_variable, (SELECT `AUTO_INCREMENT`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'lgffin'
AND TABLE_NAME = 'variable'));
END
I have the same problem and fix by add "new." before the field is updated. And I post full trigger here for someone to want to write a trigger
DELIMITER $$
USE `nc`$$
CREATE
TRIGGER `nhachung_province_count_update` BEFORE UPDATE ON `nhachung`
FOR EACH ROW BEGIN
DECLARE slug_province VARCHAR(128);
DECLARE slug_district VARCHAR(128);
IF old.status!=new.status THEN /* neu doi status */
IF new.status="Y" THEN
UPDATE province SET `count`=`count`+1 WHERE id = new.district_id;
ELSE
UPDATE province SET `count`=`count`-1 WHERE id = new.district_id;
END IF;
ELSEIF old.province_id!=new.province_id THEN /* neu doi province_id + district_id */
UPDATE province SET `count`=`count`+1 WHERE id = new.province_id; /* province_id */
UPDATE province SET `count`=`count`-1 WHERE id = old.province_id;
UPDATE province SET `count`=`count`+1 WHERE id = new.district_id; /* district_id */
UPDATE province SET `count`=`count`-1 WHERE id = old.district_id;
SET slug_province = ( SELECT slug FROM province WHERE id= new.province_id LIMIT 0,1 );
SET slug_district = ( SELECT slug FROM province WHERE id= new.district_id LIMIT 0,1 );
SET new.prov_dist_url=CONCAT(slug_province, "/", slug_district);
ELSEIF old.district_id!=new.district_id THEN
UPDATE province SET `count`=`count`+1 WHERE id = new.district_id;
UPDATE province SET `count`=`count`-1 WHERE id = old.district_id;
SET slug_province = ( SELECT slug FROM province WHERE id= new.province_id LIMIT 0,1 );
SET slug_district = ( SELECT slug FROM province WHERE id= new.district_id LIMIT 0,1 );
SET new.prov_dist_url=CONCAT(slug_province, "/", slug_district);
END IF;
END;
$$
DELIMITER ;
Hope this help someone

MySQL - Insert Into 2 Tables on 1 Procedure

I need to create a procedure for inserting records into 2 tables, but on the second table, I want to insert the last ID that was inserted on the first table. Could anyone help me with this?
This is my query
DELIMITER //
DROP PROCEDURE IF EXISTS ROOM_FEATURE_INSERT;
CREATE PROCEDURE ROOM_FEATURE_INSERT (propID INT, featID INT, featNme VARCHAR(50))
BEGIN
-- BEGIN CHECK
IF NOT EXISTS
(
SELECT rFeatureName FROM COMPANY_T3s71.PROPERTY_RFEATURE PRFE
INNER JOIN COMPANY_T3s71.ROOM_FEATURE RFEA ON PRFE.rFeatureID=RFEA.rFeatureID
WHERE BINARY rFeatureName = featNme AND propertyID = propID
)
AND
(
SELECT rFeatureName FROM COMPANY_T3s71.ROOM_VIEW
WHERE BINARY rFeatureName = featNme
)
THEN
-- IF NOT EXISTS INSERT INTO 1st TABLE
INSERT INTO COMPANY_T3s71.ROOM_FEATURE (rFeatureName) VALUES (featNme);
END IF;
-- END CHECK
-- BEGIN CHECK 2nd TABLE
IF NOT EXISTS
(
SELECT propertyID, rFeatureID FROM COMPANY_T3s71.PROPERTY_RFEATURE
WHERE rFeatureID = featID AND propertyID = propID
)
THEN
-- IF NOT EXISTS INSERT INTO 2nd TABLE
INSERT INTO COMPANY_T3s71.PROPERTY_RFEATURE (propertyID, rFeatureID) VALUES (propID, featID);
END IF;
-- END CHECK 2nd TABLE
END
DELIMITER ;
How do we pass the featID param, when we just inserted it on the first INSERT query?
Thank you before hand.
Use SET featID = LAST_INSERT_ID(); after the first query and then use the variable
INSERT INTO COMPANY_T3s71.ROOM_FEATURE (rFeatureName) VALUES (featNme);
SET featID = LAST_INSERT_ID();
However, if the data is not insert at anytime then you have to make query in the if block to set the value for featID.

Insert into change value if duplicate entry

I have this sql query:
INSERT INTO my_table
SELECT id, name, type
FROM other_table
I have this row: 1,bob,male
And I try insert: 1,bob,male
So, I have a duplicate entry error and I want change my insert value with an increment by one so after I would have two rows:
bob,male <=NOT UPDATED
bob,male
I don't want update the existing row, if I have a duplicate entry error. The insert increments the id value. So, I think ON DUPLICATE KEY isn't the solution.
UPDATE:
If I use a trigger like this:
DELIMITER |
CREATE TRIGGER incremente_primary BEFORE INSERT ON my_table FOR EACH ROW
BEGIN
IF( EXISTS( SELECT * FROM my_table )) THEN
SET NEW.id = NEW.id + 1;
END IF;
END |
DELIMITER ;
It doesn't work because a trigger can read only one line.
As per your requirement, you need to set auto_increment property for your id and then just insert other columns except id, so that it can be auto_increment like below-
INSERT INTO my_table (name,type)
SELECT name, type
FROM other_table;
If you just want to ignore if there is duplicate then you can use-
INSERT IGNORE INTO my_table
SELECT id,name, type
FROM other_table;
make sure that the primary key isn't the name or the type. Because you can input duplicate rows as long as you do not duplicate primary keys
I find a solution, i use a cursor:
DROP PROCEDURE proc_incremente;
DELIMITER |
CREATE PROCEDURE proc_incremente()
BEGIN
DECLARE var_name, var_type VARCHAR(100);
DECLARE var_id INT;
DECLARE end TINYINT(1) DEFAULT 0;
DECLARE cursor_incremente CURSOR
FOR SELECT * FROM other_table;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET end = 1;
OPEN cursor_incremente;
loop_cursor: LOOP
FETCH cursor_incremente INTO var_id, var_name, var_type;
IF end = 1 THEN
LEAVE loop_cursor;
END IF;
WHILE ( EXISTS( SELECT * my_table WHERE id = var_id) IS TRUE) DO
SET var_id = var_id + 1;
END WHILE;
INSERT INTO my_table(id,name,type) VALUES(var_id,var_name,var_type);
END LOOP;
CLOSE cursor_incremente;
END |
DELIMITER ;
CALL proc_incremente();

Trigger to insert values from another table - Mysql

I did this to trigger when the temperature is higher or lower than the parameter set off an alarm. Ie automatically populates the fields of the table alarm.
Now I created a new row in the table alarms, the idRegisto which is foreign key, now I want that id be completed in accordance with the idRegisto other corresponding table.
Does anyone can help me please?
If you are not understanding the question I will try to clarify further.
Thank you.
------------TRIGGER-------------------
DELIMITER $$
create TRIGGER alerta
BEFORE INSERT ON registos
FOR EACH ROW
begin
Set #tempmax=0;
Set #tempmin=0;
Set #hummax=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) VALUES (#maxidAlarme,"high-temperature");
INSERT INTO sensores_tem_alarmes(idSensor,idAlarme,dataAlarme) VALUES (NEW.idSensor,#maxidAlarme,NOW());
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) VALUES (#maxidAlarme,"lower temperature");
INSERT INTO sensores_tem_alarmes(idSensor,idAlarme,dataAlarme) VALUES (NEW.idSensor,#maxidAlarme,NOW());
end if;
DELIMITER ;
------------ER------------------------
You can use an "after insert trigger"
AFTER INSERT ON registos
And take the "New.IdRegistro" to use as foreign key when populating the alarmes table.
//EDIT:
using your code:
AFTER INSERT ON registos
FOR EACH ROW
begin
Set #tempmax=0;
Set #tempmin=0;
Set #hummax=0;
...
INSERT INTO alarmes(idAlarme,descricao_alarme,idRegistro) VALUES (#maxidAlarme,"lower temperature",New.IdRegistro);
INSERT INTO sensores_tem_alarmes(idSensor,idAlarme,dataAlarme) VALUES (NEW.idSensor,#maxidAlarme,NOW());
...
I assume here that IdRegistro is a primary key (that will be autogenarated by your application or via autoincrement) of the registro table.
Register->if value higher/lower threshold -> trigger alarm -> insert sensores_tem_alarmes

mysql trigger error with 2 conditions

I want to add an after insert trigger which will do the following.
The first IF condition works normally, but when it comes to the second everything stops.
Any ideas?
USE `Syslog`;
DELIMITER $$
CREATE TRIGGER `SystemEventsR_AINS` AFTER INSERT ON SystemEventsR FOR EACH ROW
IF
(exists
(select syslogtag from SystemEventsRcounter where syslogtag=
new.syslogtag)
AND
(select simpledate from SystemEventsRcounter
where syslogtag=new.syslogtag)=new.simpledate)
THEN
UPDATE SystemEventsRcounter
SET records=records+1
WHERE SystemEventsRcounter.syslogtag=new.syslogtag;
ELSE INSERT SystemEventsRcounter (simpledate, syslogtag, records) values (new.simpledate,new.syslogtag,1);
END IF
UPDATED:
What you need is INSERT INTO ... ON DUPLICATE KEY.
CREATE TRIGGER `SystemEventsR_AINS`
AFTER INSERT ON SystemEventsR
FOR EACH ROW
INSERT INTO SystemEventsRcounter (simpledate, syslogtag, records)
VALUES (NEW.simpledate, NEW.syslogtag, 1)
ON DUPLICATE KEY UPDATE records = records + 1;
In order for it to work you need to create a unique composite index on (simpledate, syslogtag)
CREATE UNIQUE INDEX idx_u_simpledate_syslogtag
ON SystemEventsRcounter (simpledate, syslogtag);
Here is SQLFiddle demo.
If you wanted it your way then it might look like
DELIMITER $$
CREATE TRIGGER `SystemEventsR_AINS`
AFTER INSERT ON SystemEventsR
FOR EACH ROW
BEGIN
IF (
SELECT COUNT(*) simpledate
FROM SystemEventsRcounter
WHERE syslogtag = NEW.syslogtag
AND simpledate = NEW.simpledate
) > 0 THEN
UPDATE SystemEventsRcounter
SET records = records + 1
WHERE SystemEventsRcounter.syslogtag = NEW.syslogtag;
ELSE
INSERT INTO SystemEventsRcounter (simpledate, syslogtag, records)
VALUES (NEW.simpledate, NEW.syslogtag, 1);
END IF;
END$$
DELIMITER ;
Here is SQLFiddle demo.