Laravel migrate error near BEGIN on trigger PostgreSQL - php

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

Related

MySQL TRIGGER is not working with $wpdb->query when this trigger query is working well directly in mysql

HERE is my trigger query which is working fine when it is fired directly in mysql database,but when i use this query in wordpress then it doesn't work.
so can you please give me some solution that how can i run this query with wordpress?
drop trigger if exists table_1;
DELIMITER $$
CREATE TRIGGER table_1
AFTER
INSERT ON table_2
FOR EACH ROW
begin
INSERT INTO table_3 ( place_id, store_name, store_address) VALUES (new.place_id, new.store_name, new.vicinity);
end $$
DELIMITER ;
Thank you in advance.
If you want to create a trigger through wordpress you can't use the $wpdb->query() method as it doesn't support trigger creation queries. In fact the Wordpress wpdb API doesn't support this at all.
You'll have to expose the underlying mysqli API and use mysqli_multi_query by doing this:
mysqli_multi_query($wpdb->dbh, $your_trigger_query)
The mysqli_multi_query function uses the mysqli connection and does support the creation of triggers.

phpMyAdmin Trigger causes General error: 1442

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.

Error creating a trigger MYSQL PHPMyadmin

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.

Conditional Insert in mysql

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

MySql trigger error with adding a new record

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.

Categories