I am trying to build a trigger, the problems is it is not working. I have syntax problems. I need to build a trigger which will update a table with another record in the same table before the table has been been updated. The trigger below describes what i want to do but it does not work.
$deletequery = '
DELIMITER //
CREATE TRIGGER after_insert_job_sent
AFTER INSERT
ON Envato_CustomConfig_job_sent FOR EACH ROW
BEGIN
DELETE FROM `Envato_CustomConfig_Job_Queue`
WHERE Job_ID = '.$value['Job_ID'].'
AND email -'.$value['email'].';
UPDATE `envato_customconfig_job_status` SET `email_Sent_Count`= email_Sent_Count+1
WHERE Job_ID = '.$value['Job_ID'].'
END; //
DELIMITER;
insert into Envato_CustomConfig_job_sent
values ( NULL , '.$value['Job_ID'].', '.$value['email'].', now();
';
EDIT:
Why does my query append other records aswell?....
so basically it is working however on the update is add one to the last record the db. i have tried LIMIT it did not work. any ideas.
insert into Envato_CustomConfig_job_sent
values ( NULL , '37', 'email', now());
DELETE FROM Envato_CustomConfig_job_queue
WHERE Job_ID = '37'
AND email ='email';
UPDATE envato_customconfig_job_status SET `email_Sent_Count`= email_Sent_Count+1
WHERE Job_ID = '37';
Triggers, Events, Functions, and Stored Procedures reside as code stored in a particular database. Only some of them have parameter passing (such as Functions and Stored Procedures). Others just fire are their own (Events and Triggers).
What you are attempting to do is perform a delete with PHP variable information which is just a query.
At least you have the DELIMITER concept nailed down, that stands in the way as a trivial error that catches many people. But if you would have highlighted the Trigger block, you would have seen the syntax error highlighting, most likely, around the embedded WHERE Job_ID = '.$value['Job_ID'].' chunk. And since the trigger runs on triggered events such as insert, etc, it would have no clue about that chunk.
When I say highlighted, I mean in a program such as Mysql Workbench.
Related
I have a table called 'messages' (INNODB) where the user can insert their own posts.
I want to put a limitation. In my php script when the table gets to 10 records, you can not add more. The logic of the program is more or less as follows.
Step 1. I run a query to count the lines that are in the table.
Step 2. Recovered that value, I decide whether to insert a new post.
My difficulty is in properly managing the possibility of two user who do the same thing simultaneously. If the user A is in step 1 while user B has just finished entering the tenth post, user A will include the eleventh.
How to avoid it?
You can create CHAR(1) NOT NULL field and cover it with UNIQUE INDEX. This will prevent of inserting more than 10 rows.
Other solution that could work would be to create BEFORE INSERT trigger that checks number of rows and raises error if there are more than 10 (look here for sample) (but in this case you can fail with condition races).
In order to allow you to change your threshold value for the table, you can use a trigger. Because MySQL triggers don't have a "prevent INSERT" option, you need a value in your table set to NOT NULL. The trigger can then set the inserted value for that column to NULL which will prevent the INSERT if your condition check fails.
A trigger like this:
CREATE TRIGGER block_insert
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
DECLARE count INT;
SELECT COUNT(*)
FROM table_name INTO count;
IF count >= 10
THEN
SET NEW.non_nullable_value = NULL;
END IF;
END;
would fail if you inserted an 11th row, like this:
ERROR 1048 (23000): Column 'non_nullable_value' cannot be null
You may wish to set the non-nullable column's name to something that represents its use. You could improve this by having the trigger pull the limit value from a configuration table.
Update
To avoid having to use the non-nullable columns, you could alternatively create an error procedure, and CALL it from your trigger - similar to the example in the "Emulating Check Constraints" section of this page - they're referencing Oracle databases, where a check constraint achieves what you want, but MySQL doesn't support them.
The "error procedure" in the example performs an INSERT of a duplicate row into an error table, causing a unique key error and stops the parent transaction also.
Update 2
As pointed out in the comment below, multiple simultaneous transactions may get round the checks - you'll have to use LOCK TABLES <name> WRITE in order to ensure that they can't.
2/ You can also lock the MySQL table.
execute : LOCK TABLES my_table
Then do your business rules.
execute : UNLOCK TABLES
This also ensure that each action is sequentially executed. (but you have to deal with performance overhead)
Hope this could be useful.
Updated since the comments below : transaction don't work in this case
1/ You are using InnoDB, you can also use database transaction
Open transaction
Then do your business rules.
Commit or rollback your transaction
This will ensure that each action are executed one after another.
Let's say I have two tables as shown:
user
id plan course_limit username
10 0 ahmad
note: plan is enum field containing '','a','b','c'.
course
id user_id username
1 10 ahmad
Now I want when a user insert into course as shown I want the course_limit to increment by 1 for that user so that I can apply a limit.
You can create a trigger with the following code.
CREATE
DEFINER = 'root'#'localhost'
TRIGGER databasename.AI_course_each
AFTER INSERT
ON databasename.course
FOR EACH ROW
BEGIN
UPDATE user SET user.course_limit = user.course_limit + 1
WHERE user.user_id = new.user_id;
END;
Some explanation
You create a trigger that fires once for every row FOR EACH ROW that is inserted AFTER INSERT into table course.
When you insert into the table you can trigger BEFORE and AFTER the insert is done.
If you want to be able to prevent the insert you fire before, if you just want to do useful work, you fire after.
The inserted fields can be accessed via a dummy table 'new'.
So here after each insert the UPDATE statement gets executed.
More trigger options
You can also use triggers BEFORE UPDATE, AFTER UPDATE,BEFORE DELETE and AFTER DELETE.
In the update and delete cases you get an extra dummy table old that you can use to refer to the data in the table before the update or delete happened.
Lots more is possible, but I'll keep it simple for now.
See http://forge.mysql.com/wiki/Triggers for more info.
Using a trigger should solve your problem : with that, you'll be able to register SQL code, on your MySQL server, that runs when certain events occur (like insertion).
I have a mysql database with 12,000 entries, what i want setup is the ability to monitor a column in the database and if/when the column is altered for any entry it sends me an email with the details.
EDIT: I have access to mysql db, but not the script which works with it. So it should monitor it for changes...
You could create some triggers on the table, if your version of MySQL has them. A trigger can then invoke any function you care to create. A trigger has the advantage that any insertion or deletion or any update of the column will cause it to fire; you wouldn't have to change any other code to make it happen. See here for more... http://dev.mysql.com/doc/refman/5.0/en/triggers.html
Create a trigger on update
Create another table (lets call it cron_table), where the trigger will insert information of the updated row (may be old value, new value etc)
Setup a cron, which will call a script which will check the cron_table and send email if any entry is found. Cron interval can be setup according to need.
--- If you could send email from trigger, there would be no need for a separate table and cron ---
try something similar to this , you can edit the function to send you and email if the query has insert and TABLE_NAME or COLUMN_NAME in it
set up one column to be a datetimestamp.
This will update on every change of the row. There you can run a sql query either via a cron job or after every few php queries to return you the list of changed rows since the last check.
Select * from tbl_myentries where EntryUpdated > '$TimeSinceLastCheck'
you need to understand Data Manipulation Language (DML) triggers
in my sql: use
CREATE TRIGGER salary_trigger
BEFORE UPDATE ON table_name
REFERENCING NEW ROW AS n, OLD ROW AS o
FOR EACH ROW
IF n.columnName <> o.columnname THEN
END IF;
;
Create a trigger on a change on your column, then insert it to another table as log table.
Run cron job on your table that will send you an email.
I have an application where I need to INSERT an auto_increment value from a PK in another table. I know how to do this in PHP, but I need to have this done at the DB level, since I cannot change the program logic.
I am new to triggers, so I'm sure this will be an easy answer for someone. Here is what I have so far:
DELIMITER //
CREATE TRIGGER new_project AFTER INSERT ON m_quality_header
FOR EACH ROW
BEGIN
INSERT INTO m_quality_detail (d_matl_qa_ID) VALUES (NEW.h_matl_qa_ID);
END//
DELIMITER ;
I just want the value of the auto_increment value from h_matl_qa_ID to be inserted as a new record into d_matl_qa_ID. The error I get is:
"This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table'
But, I don't want to update the table that has the trigger, so why is my current code considered a 'multiple' trigger?
This is on MySQL 5.0.45-7.el5 running on a CentOS 5 server (64-bit Intel) If I have to, I can modify the PHP code, but that needs to be the last resort.
If you've tried to create the trigger before, as outis states above you can issue the command
SHOW TRIGGERS;
and it will tell you.
If that is the case, what I typically do is issue
DROP TRIGGER IF EXISTS my_trigger_name;
and then recreate the trigger.
Your trigger code, otherwise, looks OK.
DELIMITER //
DROP TRIGGER IF EXISTS new_project//
CREATE TRIGGER new_project AFTER INSERT ON m_quality_header
FOR EACH ROW
BEGIN
INSERT INTO m_quality_detail
(d_matl_qa_ID, d_matl_qa_project_test_number) VALUES (LAST_INSERT_ID(), LAST_INSERT_ID());
END//
DELIMITER ;
I have a table with the following structure,
FIELD TYPE EXTRA
faciltiy_id int auto_increment(Primary Key)
hotel_id int
facility_title varchar(20)
facility_desc varchar(300)
When I want to delete a row with a particular facility_id I use the code,
DELETE
FROM $hotel_facilities
WHERE facilities_id = '$facilities_id'";
But instead of the whole row, only the facility_title and facility_desc fields are getting deleted. If I run this query directly through phpmyadmin over the table it works correctly.
Can anyone enlighten me on what i am doing wrong?
But instead of the whole row, only the facility_title and facility_desc fields are getting deleted. If I run this query directly through phpmyadmin over the table it works correctly...
Because the facilities_id is an INT, you don't need to enclose it within single quotes:
DELETE FROM {$hotel_facilities}
WHERE facilities_id = {$facilities_id}
But I think the real issue is that an UPDATE statement is being called, rather than the DELETE statement. Mainly because a DELETE statement only deletes entire rows, not specific columns.
You need to trace over what is being called when the submit is triggered, and print to screen (either using echo or via Javascript if it's more convenient) prior to execution.