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