I've just learned the MySQL triggers and how they work. I decided to apply it on my small website.
I have a Users table where new users accounts are created and I would like to keep a history of adding new accounts in a UsersHistory table.
The error is that when I execute the following query, it gives me an error:
Query:
CREATE TRIGGER User_After_Insert
AFTER INSERT ON UsersHistory FOR EACH ROW WHEN NOT NEW.Deleted
BEGIN
SET #changeType = 'DELETE';
INSERT INTO UsersHistory (UserID, changeType)
VALUES (NEW.ID, #changeType);
END;
CREATE TRIGGER User_After_Insert1
AFTER INSERT ON UsersHistory FOR EACH ROW WHEN NEW.Deleted
BEGIN
SET #changeType = 'NEW';
INSERT INTO UsersHistory (UserID, changeType)
VALUES (NEW.ID, #changeType);
END;
The error is:
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 'WHEN NOT NEW.Deleted
BEGIN Â
SET #changeType = 'DELE' at line 1
I looked for a solution but I couldn't find.
Thanks
Have you set a DELIMITER to something different than ";"? Also, I saw some stuff I didn't know to be supported in mysql (the WHEN statements before the BEGIN blocks), so heres my suggestion:
delimiter //
CREATE TRIGGER User_After_Insert AFTER INSERT ON UsersHistory FOR EACH ROW
INSERT INTO UsersHistory (UserID, changeType) VALUES (NEW.ID, 'NEW')//
CREATE TRIGGER User_After_Delete AFTER DELETE ON UsersHistory FOR EACH ROW
INSERT INTO UsersHistory (UserID, changeType) VALUES (OLD.ID, 'DELETE')//
delimiter ;
UPDATE
Due to your comment below, I think you need to read up on trigger a bit more mate. But here's the gist.
The above statements, create triggers in the actual database. In effect, you "install" the triggers in your database schema. Running the statements in any mysql client, will create the triggers if you have appropriate account rights.
Now, from this stage on, you dont explicitly call them from PHP or anything like that. They live in the database and are called automatically when you perform certain actions. In the above case, AFTER a record is deleted from UserHistory or AFTER a record is inserted into UserHistory.
So, when you run "INSERT INTO UserHistory VALUES ..." from your php script, the database will fire the trigger automatically.
Hope that makes sence.
Related
I have made database trigger in mysql and in laravel it is working fine, however when I moved to postgresql I am getting error:
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "BEGIN"
(I am new using postgresql btw)
Here is the code I've made in migration:
DB::unprepared('CREATE TRIGGER histories_insert AFTER INSERT ON packets FOR EACH ROW
BEGIN
IF new.status = "pending" THEN
insert into `histories` (`packet_id`, `message`, `created_at`, `updated_at`) VALUES (new.id, "Barang berhasil di buat", now(), now());
END IF;
END');
I really got confused about it. Hope someone can help me :)
The syntax and structure in mysql and postgre is different, in Postgres we have to write the trigger function (procedure) first then we called it in the body of our trigger
so after
FORE EACH ROW
There should be an
when event __type_of_event__
and then we call our trigger function
execute procedure __procedure_name__
Take a look at the doc about trigger here
and trigger procedure here
Noted that when event is optional, and the name of your field inside procedure should be change into plain text, or wrap it with double quotes (if it mixed with capital letter)
Don't worry about the version of documentation, postgresql trigger is consistent across versions, hope this helps!
You need to make it into a procedure:
From the docs:
PostgreSQL only allows the execution of a user-defined function for the triggered action. The standard allows the execution of a number of other SQL commands, such as CREATE TABLE, as the triggered action. This limitation is not hard to work around by creating a user-defined function that executes the desired commands.
DB::unprepared('CREATE TRIGGER histories_insert
AFTER INSERT ON packets
FOR EACH ROW
EXECUTE PROCEDURE that_procudure_you_wrote_with_that_content(new)');
As mentioned by Erdi, The syntax, and structure in MySQL is different than postgres.here is how you can write your migration for postgres Database:
CREATE OR REPLACE FUNCTION histories_insert()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.status = 'pending' THEN
INSERT INTO histories (packet_id, message, created_at, updated_at)
VALUES (NEW.id, 'Barang berhasil di buat', NOW(), NOW());
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER histories_insert
AFTER INSERT ON packets
FOR EACH ROW
EXECUTE FUNCTION histories_insert();
Actually I use PHP to insert some value into SQL server database table that contain one trigger that i have already created.
any error detected while the execution but I don't find the row.
But if I delete my trigger and I run the program again the row is inserted correctly.
Please help me.
Trigger code :
CREATE TRIGGER test6
ON dbo.test
AFTER INSERT
AS
BEGIN
Select * from dbo.tabletest
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
END
GO
Hi this is my first Question here so I'm just posting some of my code here if you need some more information on the problem please ask.
I'm trying to create a trigger is MYSQL via PHPMyadmin (yes I know not the best tool).
The idea is to be able to clean a string before the insert query executes. Simple enough.
My code:
CREATE TRIGGER `CLEAR` BEFORE INSERT ON `TABLE`
FOR EACH ROW BEGIN
SET NEW.LNAME = REPLACE(NEW.LNAME,'?','');
END;
However I keep getting this error message
#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 '' at line 3
I have no idea why. any ideas are welcome thanks before hand.
Also excuse my not so good ise of the english language, I'm not a native speaker.
You've got to change the DELIMITER before the CREATE statement and set it back afterwards:
DELIMITER |
CREATE TRIGGER `CLEAR` BEFORE INSERT ON `TABLE`
FOR EACH ROW BEGIN
SET NEW.LNAME = REPLACE(NEW.LNAME,'?','');
END |
DELIMITER ;
otherwise you could write your trigger so it needs no delimiter:
CREATE TRIGGER `CLEAR` BEFORE INSERT ON `TABLE`
FOR EACH ROW
SET NEW.LNAME = REPLACE(NEW.LNAME,'?','')
Because there's only one statement executed in the trigger body, you don't have to enclose it in a BEGIN... END block and have no need of the semicolon to enc the statement too.
I am having two table consider table1 and table2. I need to do a trigger after inserting into table1.
Trigger has to do some thing like retrieving data from two other tables using select query (it retrieves more than one row) do some calculations with the data retrieved and then it need to insert it into table2 as single row.
I think it's not possible to do these with in a trigger, so I decided to call a php file from that trigger which does all those things. But some persons says calling php from a trigger is not practically good and it has some security risk.
A Simple Example will help you out.
$sql="INSERT INTO `table1` (FirstName, LastName, Age)
VALUES ('$firstname', '$lastname', '$age')";
$result = mysql_query($sql) ;
if($result)
{
// Record successfully inserted , place your code which needs to be executed after successful insertion
}
else
{
// Insertion failed
}
I assume you would be using mysqli and not mysql becuase mysql_query is deprecated as of PHP 5.5.0 but this is just an example to help you understand the logic.
Ok got you .. In this case you need to create a TRIGGER something like this.
CREATE
TRIGGER `event_name` BEFORE/AFTER INSERT/UPDATE/DELETE
ON `database`.`table`
FOR EACH ROW BEGIN
-- trigger body
-- this code is applied to every
-- inserted/updated/deleted row
END;
This Question has already been answered check the link below.
MySQL trigger On Insert/Update events
Hope this helps.
I am really a beginner in mysql. In oracle we can use triggers , which can detect the insert elements and allows to fully break the insert command if something is wrong. I've found that mysql also supports triggers, but how can we use them for detecting insert parameters and stopping them to be inserted if they don't satisfy rules.
e.g. INSERT INTO accounts (userId, balance) VALUES ('12','450'); // Valid
INSERT INTO accounts (userId, balance) VALUES ('12','-574'); // Invalid
if(balance<0){
Do not insert;
}
else{
Insert;
}
NOTE: I'm dealing with concurrent transactions, so STRICTLY need triggers, i.e. lowest level error detection so that no one can hack.
Any help will be appreciated. Thanks,
Or use an BEFORE INSERT trigger
DELIMITER $$
CREATE TRIGGER au_a_each BEFORE INSERT ON accounts FOR EACH ROW
BEGIN
IF new.balance > 0 THEN
BEGIN
INSERT INTO b (id,balance) VALUES (new.id, new.balance);
END
END $$
DELIMITER ;
More info in the mysql documentation : http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
PS: Programming lesson number 1(One with capital "o") - Befriend whatever programming/scripting language's documentation
You may use INSERT IGNORE and set ALTER TABLE field constraints in mysql