How to log MySQLi querys in a new table - php

Using PHP5, with the MySQLi class for executing MySQL queries, how can I log each query processed using MySQLi::query in a new table in the currently connected database?
Is it possible to do some extension on the function, like in Java?

If you use version of mysql that supports triggers. Just create a trigger, this way you will not have to pollute code with unnecessary business logic
http://dev.mysql.com/doc/refman/5.0/en/triggers.html
Support for triggers is included beginning with MySQL 5.0.2. So when you deploy your app create triggers at the same time you create tables.

Define a table for your logs
create table querylog (
tm timestamp,
query varchar(4096));
and when you do a query, log the query string in this table
insert into querylog (tm, query)
values(now(), '$query_string')
You can do this either explicit at every query or in a function my_query, you define and call instead of mysqli_query or, as #E_p suggested, in a trigger.

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.

what's wrong with this sql trigger statement

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.

laravel how to use query builder DB::table(..) with DB::connection()

I have 2 databases defined in config/databases, mysql and mysql2
The default connection is mysql
I need to get this data from mysql2
$programs=DB::table('node')->where('type', 'Programs')->get();
The docs tell me I can change the connection using
$programs=DB::connection('mysql2')->select(...)
which would let me run a sql statement to get an array for $programs.
But I am wondering if there is a way to combine the 2 statements i.e. use query builder on specific db::connection.
You should use:
$programs=DB::connection('mysql2')->table('node')->where('type', 'Programs')->get();

MySQL ROLLBACK not actually rolling back

I have the following PHP code:
$dbh->beginTransaction();
$dbh->exec("LOCK TABLES
`reservations` WRITE, `settings` WRITE");
$dbh->exec("CREATE TEMPORARY TABLE
temp_reservations
SELECT * FROM reservations");
$dbh->exec("ALTER TABLE
`temp_reservations`
ADD INDEX ( conf_num ) ; ");
// [...Other stuff here with temp_reservations...]
$dbh->exec("DELETE QUICK FROM `reservations`");
$dbh->exec("OPTIMIZE TABLE `reservations`");
$dbh->exec("INSERT INTO `reservations` SELECT * FROM temp_reservations");
var_dump(GlobalContainer::$dbh->inTransaction()); // true
$dbh->exec("UNLOCK TABLES");
$dbh->rollBack();
Transactions are working fine for regular updates/inserts but the above code for some reason is not. When an error happens above, I'm left with a completely empty reservations table. I read on the PDO::beginTransaction page that "some databases, including MySQL, automatically issue an implicit COMMIT when a database definition language (DDL) statement such as DROP TABLE or CREATE TABLE is issued within a transaction". The MySQL manual has a list of "Data Definition Statements", which I would assume is the same as DDL mentioned above which lists CREATE TABLE but I am only creating a temporary table. Is there any way around this?
Also, does the fact that I'm left with an empty reservations table show that a commit occurred after the DELETE QUICK FROM reservations query?
Edit: On an additional note, the INSERT INTO reservations line also produces the following error:
Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
I tried doing $dbh->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY , true); but this doesn't seem to affect it. I'm assuming it would have something to do with the transaction, but I'm not sure. Can anyone pinpoint what exactly is causing this error as well?
Your OPTIMIZE TABLE statement is causing an implicit commit.
I'm not sure exactly what you're trying to do, but it looks you can shorten your code to:
$dbh->exec("OPTIMIZE TABLE `reservations`");
All the other code is just making the job more complex, for no gain.
I'm also assuming you're using InnoDB tables, because MyISAM tables wouldn't support transactions anyway. Every DDL or DML operation on a MyISAM table implicitly commits immediately.
By the way, buffered queries have nothing to do with transactions. They have to do with fetching SELECT result sets one row at a time, versus fetching the whole result set into memory in PHP, then iterating through it. See explanation at: http://php.net/manual/en/mysqlinfo.concepts.buffering.php

PDO::ATTR_AUTOCOMMIT ignores non-transactional INSERT/UPDATE

Been scratching my head on this for a while....
I have a PDO object with pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,0); as I want to use FOR UPDATE with some InnoDB tables. Reading the MySQL documentation, FOR UPDATE will only lock read rows if:
You are in a transaction
You are not in a transaction and set autocommit=0 has been issued
So, I am using ATTR_AUTOCOMMIT to allow the PDO object to lock rows. In either case, this is causing INSERT and UPDATE statements to not apply. These statements are nothing to do with FOR UPDATE they are just running through the same PDO object with prepared statements.
My MySQL query log looks like:
xxx Connect user#host
xxx Query set autocommit=0
xxx Query INSERT INTO foo_tbl (bar, baz) VALUES ('hello','world')
xxx Quit
PHP/PDO doesn't complain, but selecting from the table shows that the data hasn't been written.
The queries that I am running have been run thousands of time prior; only the ATTR_AUTOCOMMIT change has been made. Removing that option makes everything work again. Transactions are working fine with the option autocommit=0 too.
Are there additional calls that need making on the PDO object (commit() complains rightly that it isn't in a transaction) to make the changes stick? Basically, I want a plain PDO object but with the option to lock rows outside of transactions for InnoDB tables (the background to why is too long and boring for here).
I'm sure this is something stupid I am missing scratches head
$db = new PDO('mysql:dbname=test');
$db->setAttribute(PDO::ATTR_AUTOCOMMIT,0);
var_dump($db->query('SELECT ##autocommit')->fetchAll()); //OK
$db->query("INSERT INTO foo (bar) VALUES ('a');");
$db->query("COMMIT;");//do by SQL rather then by interface / PDO-method
But essentially, you're in a transaction (you just haven't started it with PDO), a rollback etc. is also still available. It's quite debatable whether this is a bug (not being able to call commit() directly).

Categories