MySQL - Insert Into 2 Tables on 1 Procedure - mysql

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.

Related

Dynamic name tablе in trigger

There is a trigger that copies columns from one table to another. How do I assign a table name to a dynamic variable #nametable?
Every day the name of the table changes depending on the current date.
USE dbo;
DROP TRIGGER IF EXISTS `update_test`;
GO
DELIMITER |
CREATE TRIGGER `update_test` AFTER INSERT ON `hello_send`
FOR EACH ROW
BEGIN
DECLARE nametable VARCHAR(128);
SET #nametable =(DATE_FORMAT(NOW(),"%d%m%Y_v"));
INSERT INTO `dbo`.`nametable` SET
`TIME_` =NEW.`recorded`,
`P1` = NEW.`value1`
ON DUPLICATE KEY UPDATE
`TIME_` = NEW.`recorded`,
`P1` = NEW.`value1`;
END;
Have error ERROR 1146: Table 'dbo.nametable' doesn't exist
I decided to do so as a temporary solution:
CREATE TRIGGER `update_test` AFTER INSERT ON `hello_send`
FOR EACH ROW
BEGIN
SET #dateNameTableNOW =(DATE_FORMAT(NOW(),"%d%m%Y_v"));
SET #dateNameTableSELECT1 = '06122017_v';
SET #dateNameTableSELECT2 = '07122017_v';
IF(#dateNameTableNOW = #dateNameTableSELECT1) THEN
INSERT INTO dbo.06122017_v SET TIME_=NEW.recorded, P1 = NEW.value1 ON DUPLICATE KEY UPDATE TIME_ = NEW.recorded, P1 = NEW.value1;
END IF;
IF(#dateNameTableNOW = #dateNameTableSELECT2) THEN
INSERT INTO dbo.07122017_v SET TIME_=NEW.recorded, P1 = NEW.value1 ON DUPLICATE KEY UPDATE TIME_ = NEW.recorded, P1 = NEW.value1;
END IF;
END;

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();

IF NOT EXISTS in mysql showing syntax error

I am trying to convert this tsql to mysql but showing error need help
CREATE PROCEDURE FormAdd
#formName varchar(MAX)
AS
IF NOT EXISTS(SELECT * FROM tbl_Form WHERE formName=#formName)
BEGIN
INSERT INTO tbl_Form
(formName)
VALUES
(#formName)
SELECT ##identity
END
ELSE
BEGIN
SELECT '-1'
END
mysql
CREATE PROCEDURE FormAdd
(p_formName varchar(500) )
begin
INSERT INTO tbl_Form (formName)
VALUES (p_formName)
where NOT EXISTS(SELECT * FROM tbl_Form WHERE formName=p_formName) ;
SELECT Last_insert_id() as returnvalue ;
SELECT '-1' ;
end
Your attempt was syntactically invalid because logically, an INSERT statement cannot contain a WHERE clause since it does not act on existing rows.
If the purpose is to insert only if the value for p_formname is not already present, then an appropriate step would be to define a unique index on that column first. Then, construct your procedure to attempt the insert and inspect the ROW_COUNT() value to see if one was inserted and act accordingly, returning -1 if not to adapt your existing T-SQL procedure.
First create the unique index on p_formname:
ALTER TABLE tbl_Form ADD UNIQUE KEY `idx_formName` (`formName`);
Then your procedure should use INSERT INTO...ON DUPLICATE KEY UPDATE to attempt to insert the row. Per the documentation, the value of ROW_COUNT() will be 0 if a new row was not inserted or 1 if it was.
CREATE PROCEDURE FormAdd (p_formName varchar(500))
BEGIN
/* Attempt the insert, overwrite with the same value if necessary */
INSERT INTO tbl_Form (formName) VALUES (p_formName) ON DUPLICATE KEY UPDATE formName = p_formName;
/* Return the LAST_INSERT_ID() for a new row and -1 otherwise */
SELECT
CASE
WHEN ROW_COUNT() = 1 THEN LAST_INSERT_ID()
ELSE -1
END AS returnValue;
END

MYSQL Insert values from another table - trigger

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;

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.