Does mysqli prepare cache results? - php

I've read that if you used mysqli prepare instead of mysqli query it will be run on database only once even if you run the script 1000 times.
does that mean that if i ran a prepare statement like
select * from Table where user=?"
and then mysqli_stmt_bind_param($stmt, "s", "Harry");
and user "harry" doesn't exist in the database so num_rows will return 0.and then i insert immediately a new row in the database with user="harry" and ran the script again, will it return num_rows=1 or still return num_rows=0 because the result is cached?

The fact that you see the newly inserted row depends on other factors... transaction and transaction isolation. Preparing the statement just means that the server knows what is coming and has calculate a plan to optimize the statement. You can then run the query many times, with the same or with different parameters, and the server will not have to analyze it any more... just execute it.
So... to answer your question... the second time you should get num_rows=1. But in case you don't, the problem is not that you prepared a query with parameters... it's something else.

Related

PHP PDO - Multiple Statements - if 1 fails, don't execute the other

So I've got this PHP Service which is connect to my Android app and it executes 2 queries at once. I've read how to detect if one fails and I know that one of mine fails because EventSlots is already 0 and is an INT unsigned.
However, the other statement is successful and gets executed. Obviously, I want to only execute both, and if 1 fails, don't execute anything at all but return an error for my App.
How would I detect if one of the statements failed and STOP the other from executing? I probably can avoid using multiple statements and do 1, check if it was OK and only then execute the other. Can I achieve that with multiple statements though?
Query:
"INSERT INTO GuestList(EventID, AccountID) VALUES (7, (SELECT AccountID FROM Accounts WHERE Username = 'test'));
UPDATE Events SET EventSlots = EventSlots-1 WHERE EventID = 7 ;"
Use PDO transactions http://php.net/manual/en/pdo.transactions.php . A transaction represents a bunch of queries that has to be executed in a atomic way. If something fails during the transaction it will automatically performs a rollback to the initial state.

best way to start a mysql transaction in php mysqli and PDO

how can i start a transaction in mysqli and PDO? and how can i commit it? i have seen 2 ways : using autocommit(false) and begin_transaction methods , but which one is the best way? i got headache! autocommit(false) or begin_transaction?
Your question isn't clear still I'm answering it. It is straightforward to begin and commit a transaction. In PDO, do something like this:
<?php
$pdo = // connect to database with PDO
$pdo->beginTransaction();
// query database here
$result = // query result
if($result) {
// if result is okay
$pdo->commit();
} else {
$pdo->rollBack();
}
?>
**Explanation: **
First of all, you start a transaction
Next, you query database
If result is okay, commit the transaction
If result is not okay, rollBack and the query will not execute
Reference: http://php.net/manual/en/pdo.transactions.php
About Auto-commit: In auto-commit mode, each query is a complete transaction and it is executed instantly. By default, PDO auto-commits each query. Turning off the auto-commit will need you to commit the query manually. In general scenario, you should not turn it off.
When you need to execute an important query, i.e multi-part queries that depend on each other for their final result like an amount transfer between two accounts (where you need to deduct amount from one table and to add it to another table), simply begin a transaction. PDO will not execute any query until you commit the transaction. If something goes wrong, everything will be rolled back to its previous state.
Lastly, there isn't any big difference between turning off auto-commit and beginning a transaction. By beginning transactions, you can simplify the tasks otherwise you will need to manually commit each query regardless of its nature.
I hope it answers your question.

When I execute a prepared statement to select rows in a db table, does pdo "fetch" the records and caches it?

When I execute a prepared statement to select rows in a db table, does pdo "fetch" the records and caches it?
i.e. If I perform a fetch after executing a "select" statement, does pdo perform multiple db calls for each record I want fetched or does it simply fetch each record from its cache? (assuming it has cache)
tnx.
When you ask does pdo perform multiple db calls for each record if you mean a database connection or query by saying calls, then no. the way it works pdo opens the connection, query once then if you use fetchAll() it gets all the values at once while fetch() will get one value at the the time.
The caching you are referring when using prepare() a and execute() for statements that will be issued multiple times with different parameter values optimizes the performance of your application by allowing the driver to negotiate client and/or server side caching of the query plan and meta information.
Unless you are fetching huge amount of records (into the memory) you should not be concern with the cost of using fetch.
Sooo.. to answer your question PDO will not cache fetch , it will be stored into memory.

pg_prepare: cannot insert multiple commands into a prepared statement

I have 2 tables, TableA and TableB. TableB has a fk field pointing to TableA.
I need to use a DELETE statement for TableA, and when a record in it is deleted I need to delete all records in TableB related to that record in TableA. Pretty basic.
begin;
DELETE FROM TableB
WHERE nu_fornecedor = $1;
DELETE FROM TableA
WHERE nu_fornecedor = $1;
commit;
This string is passed to pg_prepare(), but then I get error
ERROR: cannot insert multiple commands into a prepared statement
Ok, but I need to run both commands in the same transaction, I cant execute 2 separated statements. I tried to use with without begin-commit and got same error.
Any idea how to do it?
To understand what is going on and your options, let me explain what a prepared statement is and what it is not. You can use pg_prepare, but only for the statements individually, not for the transaction as a whole.
A prepared statement is a statement handed to PostgreSQL which is then parsed for and stored as a parse tree for future use. On first execution, the parse tree is planned with the inputs provided, and executed, and the plan cached for future use. Usually it makes little sense to use prepared statements unless you want to reuse the query plan (i.e. executing a bunch of otherwise identical update statements hitting roughly the same number of rows), all in the same transaction.
If you want something that gives you the benefits of separating parameters from parse trees but does not cache plans, see pg_query_param() in the PHP documentation. That is probably what you want.

When to close Prepared Statement

When to close prepared statements in PHP?
Example:
$query = "insert into web_reviews (title,added_date,reviewer_home_url,read_more_link,summary) values(?,?,?,?,?)";
$stmt = $this->db->prepare($query);
$stmt->bind_params($this->title,$this->added_date,$this->reviewer_home_url,$this->read_more,$this->summary);
$stmt->execute() or die("Cannot add the date to the database, please try again.");
$stmt->close();
$stmt = $this->db->prepare("select id from web_reviews where title = ? and read_more = ?");
$stmt->bind_params($this->title,$this->read_more);
$stmt->execute();
$stmt->bind_results($web_review_id);
$stmt->close();
Should I use $stmt->close(); here?
Edit:
What is written on the PHP Manual and also one comment from the manual says:
Closes a prepared statement.
mysqli_stmt_close() also deallocates
the statement handle. If the current
statement has pending or unread
results, this function cancels them so
that the next query can be executed.
Comment:
if you are repeating an statement in
an loop using bind_param and so on
inside it for a larger operation. i
thougt id would be good to clean it
with stmt->close. but it broke always
with an error after aprox. 250
operations . As i tried it with
stmt->reset it worked for me.
That is a good use of close, especially since you are planning on making another query. With both PDO statements and MySQLi statements, I find that erring on the side of cleanliness is almost always for the best -- it removes potential bugs down the line.
As to the gentlemen with 250 operations... I don't see what the real use case is. Why does he need to query the database 250 different times? Why can't he query the database once with 250 records? Or, more likely, why can't he query the database 25 times with 10 records?
I am unable to comment currently, so I am just providing an answer. When you run a prepared statement that queries the database for a result, it will not execute another query unless you remove the current result it is storing. $result = $stmt->get_result().
Secondly, If you will need the result from the first query to be saved so that you use it later, then I recommend using two result sets. The first stores the result from the first execution of $stmt and the second for the second execution. This might not answer the question directly, but it may help someone.

Categories