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.
Related
I am uploading data into temp table after uploading. I need to performs joins and select few columns and push those data to another table in php . Is there any way of doing it without using triggers
If you don't want to use a trigger to react to an insertion in a database, you pretty much need to do it by polling that table to see if there is new insertions at a given time interval. You will need a flag in that polled table to know if a row has already been processed in a previous run to prevent reacting multiple times for a single insert.
One way of doing this could be with a CRON job ran at every minutes that execute a php script that simply "select all rows of your table where the "isProcessed" flag is false". Of course the default value for the "isProcessed" column must be false.
Then for each row obtained with the previous DB query, you do what you want to do, i.e. "performs joins and select few columns and push those data to another table in php" to quote yourself.
Then update the same rows in your original "temp" table so that their "isProcessed" is now at true.
I guess you have a good reason not to use database triggers , because triggers are there to do exactly what you want to do in the simplest way that it can be done.
We have an automatic car plate reader which records plates of the cars enter to firm. My colleague asked me if we can instantly get the plate number of the car coming. The software uses MySQL and I have only database access. Cannot reach/edit PHP codes.
My offer is to check using a query periodically. For example for 10 seconds. But in this way it is possible to miss the cars coming in 5 seconds. Then decreasing interval increases request/response count which means extra load for the server. I do not want the script to run always. It should run only a new db row added. It shows the plate and exits.
How can I get last recorded row from the db right after inserting? I mean there should be trigger which runs my PHP script after insertion. But I do not know.
What I want is MySQL could run my PHP script after a new record.
If your table is MyISAM, I would stick to your initial idea. Getting the row count from a MyISAM table is instant. It only takes the reading of one single value as MyISAM maintains the row count at all times.
With InnoDB, this approach can still be acceptable. Assuming car_table.id is primary key, SELECT COUNT(id) FROM car_table only requires an index scan, which is very fast. You can improve on this idea by adding another indexed boolean column to your table:
ALTER car_table ADD COLUMN checked BOOLEAN NOT NULL DEFAULT 0, ADD INDEX (checked);
The default value ensures new cars will be inserted with this flag set to 0 without modifying the inserting statement. Then:
BEGIN TRANSACTION; -- make sure nobody interferes
SELECT COUNT(checked) FROM car_table WHERE checked = FALSE FOR UPDATE; -- this gets you the number of new, unchecked cars
UPDATE car_table SET checked = TRUE WHERE checked = FALSE; -- mark these cars as checked
COMMIT;
This way, you only scan a very small number of index entries at each polling.
A more advanced approach consists in adding newly created cars ID's into a side table, through a trigger. This side table is scanned every now and then, without locking the main table, and without altering its structure. Simply TRUNCATE this side table after each polling.
Finally, there is the option of triggering a UDF, as suggested by Panagiotis, but this seems to be an overkill in most situations.
Although this is not the greatest of designs and I have not implemented it, there is way to call an external script through sys_exec() UDF using a trigger as mentioned here:
B.5.11: Can triggers call an external application through a UDF?
Yes. For example, a trigger could invoke the sys_exec() UDF.
http://dev.mysql.com/doc/refman/5.1/en/faqs-triggers.html#qandaitem-B-5-1-11
Also have a look on this thread which is similar to your needs.
Invoking a PHP script from a MySQL trigger
I have table with fields:
id
data1
data2
next I want to set trigger that after update would write to log table changes:
CREATE TRIGGER `update_data` AFTER UPDATE on `data_table`
FOR EACH ROW
BEGIN
IF (NEW.data1 != OLD.data1) THEN
INSERT INTO data_tracking set old_value = OLD.data1, new_value = NEW.data1, field = "data1";
END IF;
-- similar for data2
END$$
I also want to record in data_tracking table user that made change, however this user is not part of original UPDATE that trigger the trigger. I it a way to let trigger know what user need to be recorded ?
This is PHP based web service with multiple registered users, that can make changes to record via website - those user i would like to add to trigger.
As you want to use the user name that only is known to PHP, well, MySql cannot know which user triggered the change if this information is only available in PHP. This means you would at least have to pass the user in every update statement, either adding this as a column to all tables that need this kind of trigger, or do all the updates via stored procedures that get the user name as an additional parameter. Then you could get rid of all the triggers, as you would use stored procedures anyway that can do the logging as well as the updates.
Use CURRENT_USER, see the MySQL manual: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_current-user
So basically what I am trying to do is when a user of my site creates a new account on our register page, I'd like the primary key from the newly created row on the User table (basic info table, email, password, etc.) to be inserted into a new row on the Profile table (more descriptive info, about me, display name, etc.)
I'd like to do this in PHP and any help would be appreciated.
if you are using mysqli look at:
http://www.php.net/manual/en/mysqli.insert-id.php
Get the id after your first insert and then use this in your next insert.
If doing it "in php" isn't really a requirement, then you can use MySQL's built in Trigger mechanism to do this update.
Triggers cause something to happen AFTER or BEFORE an event(INSERT, UPDATE,DELETE)
So your trigger would be:
CREATE TRIGGER thistrigger AFTER INSERT
ON User FOR EACH ROW
UPDATE PROFILE SET "whatever"
On Triggers: http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
I think there isn't a really elegant way in MySQL, basically because INSERT doesn't return anything. PostgreSQL does allow for an INSERT ... RETURNING clause, but that's an extension.
That said, if you're using the mysql_* functions in PHP, you can use mysql_insert_id, which might suffice for your needs (i.e. if your primary key is an AUTO INCREMENT integer).
If you are using a mysql database, you could alternatively do another query call from php with the following query:
"SELECT LAST_INSERT_ID();"
More info about it here: http://www.jpgtutorials.com/mysql-last_insert_id-function
It is connection specific. Concurrent inserts from different connections won't affect the current connection.
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).