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.
Related
I want to add 1000 unique random values to the column AgentID to the table agents.
I have used Upsert to ignore the duplicate values. What I have done so far:
DROP PROCEDURE IF EXISTS Generate_random;
DELIMITER $$
CREATE PROCEDURE Generate_random()
BEGIN
Drop table if exists ai_training.`Agents`;
CREATE TABLE ai_training.`Agents`(AgentID int PRIMARY KEY);
SET #first = 1;
SET #last = 1000;
WHILE(#first <= #last) Do
INSERT INTO ai_training.`Agents` VALUES(
FLOOR(RAND()*(2900000-2800000+1)+2800000)
)
ON DUPLICATE KEY UPDATE AgentID = FLOOR(RAND()*(2900000-2800000+1)+2800000);
SET #first = #first + 1;
END WHILE;
END$$
DELIMITER ;
CALL Generate_random();
Select * from ai_training.`Agents`;
The problem is I need 1000 unique agentid's and this code is generating 1000 - the repeated ones. So, if it finds 6 repeated ids it returns 994 rows and not 1000.
Is there any way I can achieve this?
Can't change the random ID generation part.
You could use information function ROW_COUNT() to check whether a row was actually inserted or not, and increment the counter accordingly.
The documentation states:
With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values.
So:
WHILE(#first <= #last) DO
INSERT INTO ai_training.`Agents`
VALUES(FLOOR(RAND()*(2900000-2800000+1)+2800000))
ON DUPLICATE KEY UPDATE AgentID = AgentID;
IF ROW_COUNT() = 1 THEN
SET #first = #first + 1;
END IF;
END WHILE;
Note that I changed the action on duplicate key to a dummy update rather than re-assigning a new random value; this makes things a little less expensive when a collision happens.
CREATE PROCEDURE Generate_random()
BEGIN
Drop table if exists ai_training.`Agents`;
CREATE TABLE ai_training.`Agents`(AgentID int PRIMARY KEY);
SET #last = 1000;
WHILE (SELECT COUNT(*) FROM ai_training.`Agents`) < #last DO
INSERT IGNORE INTO ai_training.`Agents`
VALUES
(FLOOR(RAND()*(2900000-2800000+1)+2800000));
END WHILE;
END
This is my first trigger in MySql and I am having a few problems. I tried both of these pieces of code but both would not compile. I got it to work without the where clause.
CREATE TRIGGER ins_meal_details
AFTER INSERT ON meal_details
FOR EACH ROW
INSERT INTO sql_changes
SET
sc_table='book_room',
sc_reason='DINNER1',
sc_key='bh_no=NEW.bh_no,date=NEW.md_date',
sc_value='1',
sc_done =0
WHERE not exists (select 1 from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1)
CREATE TRIGGER ins_meal_details AFTER INSERT meal_details FOR EACH ROW
BEGIN
IF NOT EXISTS (select 1 from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1) THEN
INSERT INTO sql_changes (sc_table, sc_reason, sc_key, sc_value, sc_done )
VALUES ('book_room','DINNER1', 'bh_no=NEW.bh_no,date=NEW.md_date','1', 0);
END IF
END
CREATE TRIGGER ins_meal_details
AFTER INSERT
ON meal_details
FOR EACH ROW
INSERT INTO sql_changes (sc_table,
sc_reason,
sc_key,
sc_value,
sc_done)
SELECT 'book_room',
'DINNER1',
CONCAT('bh_no=',NEW.bh_no,',date=',NEW.md_date),
1,
0
WHERE NOT EXISTS (SELECT 1
FROM booking
WHERE bh_no = NEW.bh_no
AND bo_date = NEW.md_date
AND bo_meals < 1);
MySql did not like the select/where exists in my code when there is no table specified. This was due to using version 5.6 of MySql server.
This will not work: select 'works' where exists (select 1 from my-table)
The fix would be thanks to #akina to add from DUAL. The best solution.
I got round it by using a count(*) instead :-
DROP TRIGGER IF EXISTS ins_meal_details;
DELIMITER //
CREATE TRIGGER ins_meal_details
AFTER INSERT ON meal_details FOR EACH ROW
BEGIN
IF (select count(*) from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1) > 0 THEN
INSERT INTO sql_changes (sc_table,
sc_reason,
sc_key,
sc_value,
sc_done)
VALUES ('book_room','DINNER1', CONCAT('bh_no=',NEW.bh_no,',date=',NEW.md_date),'New Value', 0);
END IF;
END//
DELIMITER ;
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.
first of all my english is not so good but i think maybe enogh. Ok, I have a procedure for inserting.
Procedure is
CREATE PROCEDURE `PhotoUpdate`(IN `uid` INT, IN `foto` VARCHAR(255))
BEGIN
INSERT INTO photos (Dosya, UyeID)
VALUES (foto, uid)
ON DUPLICATE KEY UPDATE UyeID = uid;
END
And Im calling it like this
Call PhotoUpdate(87,'87_54284.jpg');
Photos table is
id Dosya UyeID
1 55_48615.jpg 55
2 87_95165.jpg 87
Im trying to ('uid'->87) if uid equals to photos.UyeID, I mean if UyeID=87 then Update row. If else then insert.
This querys that i tryd. But didnt work.
IF EXISTS (SELECT ID FROM photos WHERE UyeID = uid)
UPDATE photos SET Dosya = foto WHERE UyeID = uid;
ELSE
INSERT INTO photos (Dosya, UyeID) Values(foto, uid);
END IF;
How can i do this guys?
Alternatively:
DELIMITER $$
DROP PROCEDURE IF EXISTS `PhotoUpdate`$$
CREATE PROCEDURE `PhotoUpdate`(`uid` INT UNSIGNED, `foto` VARCHAR(255))
BEGIN
INSERT INTO `photos` (`Dosya`, `UyeID`)
VALUES (`foto`, `uid`)
ON DUPLICATE KEY UPDATE `Dosya` = `foto`;
END$$
DELIMITER ;
SQL Fiddle demo
Try REPLACE INTO photos (Dosya, UyeID) VALUES(foto, uid);
If you create an unique index on UyeID, or even better get rid of the ID column and make UyeID the primary key, you can use INSERT .... ON DUPLICATE KEY UPDATE.
Example
INSERT INTO photos (Dosya, UyeID)
VALUES ('example.jpg', 87)
ON DUPLICATE KEY UPDATE
Dosya = VALUES(Dosya)
If you use VALUES you can use this also with a bulk insert
I have 2 triggers on my table as defined...
DELIMITER $$
CRATE TRIGGER newRecordToHistory AFTER INSERT ON myTable FOR EACH ROW
BEGIN
IF (new.recordType = 1) THEN
INSERT INTO myTableHistory
(
myTableId,
someInformation,
reason,
mytimestamp,
status
)
VALUES
(
new.myTableId,
new.someInformation,
new.reason,
now(),
'NEW'
);
END IF;
END$$
DELIMITER ;
and
DELIMITER $$
CRATE TRIGGER updateRecordToHistory AFTER UPDATE ON myTable FOR EACH ROW
BEGIN
IF (new.recordType = 1) THEN
INSERT INTO myTableHistory
(
myTableId,
someinformation,
reason,
mytimestamp,
status
)
VALUES
(
new.myTableId,
new.someInformation,
new.reason,
now(),
'UPDATED'
);
END IF;
END$$
DELIMITER ;
When I insert a new record into myTable, I get 2 records in myHistoryTable...
ID someInformation reason mytimestamp status
1 'This is new' 'Needed new record' 09/12/14 08:00:00 'NEW'
1 'This is new' 'Needed new record' 09/12/14 08:00:00 'UPDATED'
I also get a record in the table when I delete. But my code handles inserting into the history table when I delete (so the user can specify the reason for deleting it) from myTable.
I would only expect only one record in myHistoryTable on insert and no extra records in the myHistoryTtable when I delete (other than the ones I put there manually). Why does this happen? And how can I avoid this?
Thanks!