MySQL trigger if-else insert update - mysql

I'm trying to make this code work but to no avail..
DELIMITER $$
CREATE
TRIGGER `update_tbl1` AFTER UPDATE
ON `tbl1`
FOR EACH ROW BEGIN
IF (SELECT count(*) FROM tbl1 WHERE stn=NEW.stn) = 1
THEN
UPDATE tbl2 SET date_posted=NEW.date_posted WHERE stn=NEW.stn;
ELSE
INSERT INTO tbl2 (stn) VALUES (NEW.stn);
END IF
END$$
DELIMITER ;
I have two tables, and I want a trigger that will update tbl2 if the tbl1 is updated, only if the data already exists on the tbl2, otherwise, insert it. My code seems feasible and the error seems to be syntax-related but I can't find where.
EDIT:
Here is the error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO tbl2 (stn) VALUES (NEW.stn); END IF END' at line 10

About syntax error, I think it's just what you forgot semicolon ; after END IF, try following:
DELIMITER $$
CREATE
TRIGGER `update_tbl1` AFTER UPDATE
ON `tbl1`
FOR EACH ROW BEGIN
IF (SELECT count(*) FROM tbl1 WHERE stn=NEW.stn) = 1
THEN
UPDATE tbl2 SET date_posted=NEW.date_posted WHERE stn=NEW.stn;
ELSE
INSERT INTO tbl2 (stn) VALUES (NEW.stn);
END IF;
END$$
DELIMITER ;

I'm not sure what the syntax error is, but the logic you want is:
INSERT INTO tbl2 (stn)
VALUES (NEW.stn)
ON DUPLICATE KEY UPDATE SET date_posted = NEW.date_posted;
For this to work, you need a unique index on tbl2(stn):
CREATE UNIQUE INDEX unq_tbl2_stn ON tbl2(stn);
Note: This doesn't fix your particular syntax error. This addresses a logical error in the code.

Related

MySQL BEFORE INSERT trigger to turn duplicate primary keys inserts into updates

I'm trying to execute this query in a database through phpmyadmin
create trigger avoid_duplicated_sharing
before insert on sharingevents
for each row
begin
if ( select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0 ) then
delete from sharingevents where shared_note_id = NEW.shared_note AND shared_to = NEW.shared_to
END IF;
END
But phpmyadmin gives me the following error:
MySQL said: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'END IF' at line 7
Two questions:
What's wrong with my script?
After a BEFORE INSERT trigger, Will INSERT operation be performed? In case it doesn't I will have to remove INSERT INTO SharingEvents (SELECT * FROM NEW);
I solve it with the following code:
delimiter $$
create trigger avoid_duplicated_sharing
before insert on sharingevents
for each row
begin
if ( select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0 ) then
delete from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to;
end if;
END$$
The problem was the delimiter.
Even so, my trigger doesn't work. When the application inserts duplicated primary keys MySQL throws the following error:
#1442 - Can't update table 'sharingevents' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Use exists:
if (exists (select 1 from sharingevents where shared_note_id = new.shared_note_id AND shared_to = new.shared_to) > 0) then
insert into sharingevents (shared_note_id,shared_to,permission_level)
values (NEW.shared_note_id,NEW.shared_to,NEW.permission_level);
end if;
Or, better yet, add a unique index on sharingevents(shared_note-id, shared_to) and then use:
insert into sharingevents (shared_note_id, shared_to, permission_level)
values (NEW.shared_note_id, NEW.shared_to, NEW.permission_level)
on duplicate key update shared_note_id = values(shared_note_id);
This will ignore any updates where the pairs already exist in the table. No if required.
count(shared_note_id, shared_to) is invalid syntax. You can only put multiple column names inside COUNT() when you use count(DISTINCT ...). In your case, you don't need to put column names at all, just use COUNT(*) to count the number of rows matching the condition.
See count(*) and count(column_name), what's the diff? for more information about when you should put column names in COUNT()
Unfortunately, fixing the syntax errors won't really solve your problem, because you can't use a trigger to make a change to the same table. From the FAQ:
Can triggers access tables?
A trigger can access both old and new data in its own table. A trigger can also affect other tables, but it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
You'll need to recode the callers to use INSERT ... ON DUPLICATE KEY UPDATE, or something equivalent, to accomplish this.

Error writing trigger statement

I would like to limit the size of a table to X rows (I'll use 5 for example). When the limit is reached, I want to copy the oldest row to another table, then delete it. I currently have:
CREATE TRIGGER LimitRows BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
IF (SELECT COUNT(*) FROM MyTable) >= 5 THEN
INSERT INTO HistoryTable
SELECT *
FROM MyTable A
WHERE vhID = A.min(vhID);
DELETE FROM MyTable
WHERE vhID = min(vhID);
END IF;
END;
Currently, I get the error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 8
How do I write this trigger correctly? Also, how can I modify to cut the table down to 5 rows if it starts out at something like 100 rows?
You need to change the delimiter first
delimiter |
CREATE TRIGGER LimitRows BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
IF (SELECT COUNT(*) FROM MyTable) >= 5 THEN
INSERT INTO HistoryTable
SELECT *
FROM MyTable A
WHERE vhID = A.min(vhID);
DELETE FROM MyTable
WHERE vhID = min(vhID);
END IF;
END
|
delimiter ;
Otherwise the trigger definition would end at the first ; which would make it incomplete.

Trigger isn't working, error inserting into another table upon insert

I'm attempting to insert a new record into a table upon a record being inserted into primary table. However its not even registering as a trigger...
DELIMITER $$
CREATE TRIGGER trigger_InsertRoleplay ON `users`
FOR INSERT AS
BEGIN
INSERT INTO
`roleplay_users`
(
id
)
SELECT
id
FROM
INSERTED
END$$
DELIMITER ;
The error returned.
CREATE TRIGGER trigger_InsertRoleplay ON `users`
FOR INSERT AS
BEGIN
INSERT INTO
`roleplay_users`
(
id
)
SELECT
id
FROM
INSERTED
END;
/* SQL Error (1064): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ON `users`
FOR INSERT AS
BEGIN
INSERT INTO
`roleplay_users`
' at line 1 */
/* Affected rows: 0 Found rows: 0 Warnings: 0 Duration for 0 of 1 query: 0.000 sec. */
If you are using MySQL, then you probably want something like this:
DELIMITER $$
CREATE TRIGGER trigger_InsertRoleplay AFTER INSERT ON `users`
FOR EACH ROW
BEGIN
INSERT INTO roleplay_users(id)
SELECT new.id;
END$$
DELIMITER ;
INSERTED is something that SQL Server uses, not MySQL.

Trigger to update table based on another table update in mysql

I have two tables
1. Tag
2. Triger_testing
Tag desc
id int, is_active (tinyint)
Trigger_Testing Desc
tag_id (int), is_active(tinyint)
I want to create a trigger on tag table update which update trigger_testing table. So if tag.is_active is set to 0 the trigger must fire and update trigger_testing table and set trigger_testing.is_active=0 where trigger_testing.tag_id=tag.id.
I tried to create a trigger in MYSQL but getting syntax exception. Can someone help me out in resolving that issue.
Here is the code : -
CREATE TRIGGER update_trigger_testing AFTER UPDATE ON tag
FOR EACH ROW
BEGIN
IF NEW.is_active=0 THEN
UPDATE trigger_testing SET is_Active=0 WHERE tag_id=NEW.id
END IF
END$$
DELIMITER;
The error I am getting is :
Error Code: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'END IF
END$$
DELIMITER' at line 6
CREATE TRIGGER update_trigger_testing AFTER UPDATE ON tag
FOR EACH ROW
BEGIN
IF NEW.is_active=0 THEN
UPDATE trigger_testing SET is_Active=0 WHERE tag_id=NEW.id;
END IF;
END;

Trigger that Inserts to another table when new record added

I have 2 tables. The Data of profit table will come from the bet table. Therefore, automating INSERT to profit table whenever new record got added on bet table will be convenient.
How can I make sure the trigger will insert only data that doesn't exist on the profit table?
Here's what I did so far
DELIMITER $$
DROP TRIGGER IF EXISTS tsuika $$
CREATE TRIGGER keisan BEFORE INSERT ON profitdb
FOR EACH ROW BEGIN
INSERT INTO `profitdb`(`BetID`,`DateTime`, `PlayerID`,
`Profit`,`SubAgentID`,`SubAgentRisk`,`AgentID`,`AgentRisk`)
SELECT `betdb`.`BetID`,`betdb`.`DateTime`,`betdb`.`PlayerID`,
(`BetAmount`-Payout`),`playerdb`.`SubAgentID`,`subagentdb`.`Risk`,
`agentdb`.`AgentID`,`agentdb`.`Risk` FROM `betdb` LEFT JOIN `playerdb` ON
`betdb`.`PlayerID` = `playerdb`.`PlayerID` LEFT JOIN `subagentdb` ON
`subagentdb`.`SubAgentID` = `playerdb`.`SubAgentID` LEFT JOIN `agentdb` ON
`agentdb`.`AgentID` = `playerdb`.`AgentID`
END
$$
DELIMITER;
I referred to this link MySQL trigger On Insert/Update events regarding making triggers with INSERT but still getting this error
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'END' at line 5
You must end all executable statements with default delimiter, i.e. ';' semi-colon in a code block.
You missed a semi-colon after select statement.
And you are trying to drop an irrelevant trigger 'tsuika'. It should be the current trigger you are trying to create or re-define. Change it to 'keisan'.
DELIMITER $$
DROP TRIGGER IF EXISTS keisan; $$ -- <--- this was with wrong trigger name. corrected.
CREATE TRIGGER keisan BEFORE INSERT ON profitdb
FOR EACH ROW BEGIN
INSERT INTO `profitdb`(`BetID`,`DateTime`, `PlayerID`, `Profit`,
`SubAgentID`,`SubAgentRisk`,`AgentID`,`AgentRisk`)
SELECT `betdb`.`BetID`, `betdb`.`DateTime`, `betdb`.`PlayerID`,
( `BetAmount` - `Payout` ), `playerdb`.`SubAgentID`,
`subagentdb`.`Risk`, `agentdb`.`AgentID`, `agentdb`.`Risk`
FROM `betdb`
LEFT JOIN `playerdb`
ON `betdb`.`PlayerID` = `playerdb`.`PlayerID`
LEFT JOIN `subagentdb`
ON `subagentdb`.`SubAgentID` = `playerdb`.`SubAgentID`
LEFT JOIN `agentdb`
ON `agentdb`.`AgentID` = `playerdb`.`AgentID`; -- <--- missed
END;
$$
DELIMITER ;