I set a trigger in phpMyAdmin with MySQL database with AFTER and INSERT:
update table1
set col1= col2
Then when I go and insert a row, this error message shows up:
Error 500
CDbCommand failed to execute the SQL statement: SQLSTATE[HY000]: General error: 1442 Can't update table 'card' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Any ideas?
The error message in this particular case is quite explicit: you are trying to modify the very table in the trigger on which the trigger itself was invoked and this is not allowed in mysql. See mysql documentation on Restrictions on Stored Programs:
A stored function or trigger cannot modify a table that is already
being used (for reading or writing) by the statement that invoked the
function or trigger.
If you know that col1 has to have the same value as col2, then set it in the insert statement itself. If the logic is more complicated than this, then use a stored procedure to execute the insert and the subsequent update and leave triggers out of it.
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
I am writing my first sql trigger query.So i am trying to grasp the idea of trigger statement.My plan is to--
1.insert data to a table called 'trigger_table';
2.After insertion ,fetch data from that exact same table and store it to a php variable using PDO;
So i wrote the following trigger statement.And i get this error while executing sql in mysql workbench
ERROR 1415: Not allowed to return a result set from a trigger
SQL Statement:
CREATE TRIGGER `trigger_table_AINS` AFTER INSERT ON trigger_table FOR EACH ROW
-- Edit trigger body code below this line. Do not edit lines above this one
BEGIN
SELECT * FROM trigger_table;
END
It would be a great help if anyone guide me towards the right path to accomplish my task.Thanks !
php code:
$db=new PDO("mysql:host=localhost;dbname=trigger",'root','');
$sql="INSERT INTO trigger_table (name,email) VALUES('zami','alzami#gmail.com')";
$conn=$db->prepare($sql);
if($conn->execute()){
$result=$conn->fetchAll(PDO::FETCH_OBJ);
}
Triggers are meant to react to an event to update, modify or delete content. As the error states, they aren't meant to return data.
Per the documentation:
A trigger is a named database object that is associated with a table, and that activates when a particular event occurs for the table. Some uses for triggers are to perform checks of values to be inserted into a table or to perform calculations on values involved in an update.
You may be after a Stored Routine
Stored routines (procedures and functions) are supported in MySQL 5.7. A stored routine is a set of SQL statements that can be stored in the server. Once this has been done, clients don't need to keep reissuing the individual statements but can refer to the stored routine instead.
I have a mysql table which has a trigger attached, that logs changes in this table to a second one
CREATE TRIGGER log_table BEFORE UPDATE ON table1
FOR EACH ROW BEGIN
INSERT INTO log_table(filed) VALUES(NEW.field);
END;
//
Now if I perform an INSERT INTO table1 from PHP an call mysqli_insert_id() afterwards.
Would that return the new ID in table1? Or the new ID in log_table?
LAST_INSERT_ID() called after the INSERT statement will return the new ID in table1 (of the INSERT statement), not the one in the log_table (of the trigger).
This is documented in the manual section of LAST_INSERT_ID:
Within the body of a stored routine (procedure or function) or a
trigger, the value of LAST_INSERT_ID() changes the same way as for
statements executed outside the body of these kinds of objects. The
effect of a stored routine or trigger upon the value of
LAST_INSERT_ID() that is seen by following statements depends on the
kind of routine:
If a stored procedure executes statements that change the value of
LAST_INSERT_ID(), the changed value is seen by statements that follow
the procedure call.
For stored functions and triggers that change the value, the value is
restored when the function or trigger ends, so following statements
will not see a changed value.
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.