What is the difference between mysqli::query and mysqli::real_query?
OR
What is the difference between mysqli_query and mysqli_real_query?
mysqli::query will return a result if there is any.
mysql::real_query will return true on success or false if not
You could have seen this in the php doc:
query,
real_query.
Look at the documentation of mysqli_query():
Functionally, using this function is identical to calling
mysqli_real_query() followed either by mysqli_use_result() or
mysqli_store_result().
From what I understand real_query actually executes the query, and use/store_result initiates the process of retrieving a result set for the query.
query() does both.
Bit late, but the biggest advance for me is the RAM usage when these functions are called with default settings: with mysqli_real_query() you do not copy the whole result into the RAM, which mysqli_query() by default does (although it can be changed by using the $resultmode parameter).
In practice there is another difference I don't see in other answers. You could need to use mysqli_real_query() for a CALL statement.
If you are calling a stored procedure, then it can return more than one result. mysqli_query() will fetch the first result, but could be more results that needs to be fetched, and that would cause an error. You need to use mysqli_real_query(or mysqli_multi_query()) to fetch those result sets.
Sadly that explanation is in the stored procedures section of the PHP docs, so is hard to reach.
I let you a code example, just in case, calling a procedure that suppose to return several result sets using mysqli::real_query:
$query="CALL storedProcedure()";
if($conn->real_query($query)){
do{
if($result=$conn->store_result()) {
while($row=$result->fetch_assoc()) {
print_r($row);
}
$result->free();
}
}while($conn->more_results() && $conn->next_result());
}
Related
After working with Nodejs, i got used to various promise-based api's that would throw an exception/error in case of some error.
In both Codeigniter and Laravel, i see that the ALL examples of querying sort of "assume" that everything "will be ok": no try-catch or any other form of error handling.
For instance, i see that CI's "insert" method returns true on success, false on failure. Despite that, none of the examples i've seen, uses any if/else Boolean check on the operation. Same goes for Laravel, which is obviously a much more modern and professional framework.
What i did for now, is to manually check for "true" or "false", for every query that returns a boolean, but the problem is some methods return other types, like the "insert_batch" methods, whose return type is stated as "mixed".
Can someone shed a light on this issue? What approach do others take, to make sure nothing breaks, due to poor database error handling?
A link for the relevant section in CI's docs:
https://www.codeigniter.com/user_guide/database/query_builder.html?highlight=query%20builder
The "read" queries - get() and get_where() - are not documented correctly. It says the return is a CI_DB_result but it can also return FALSE. I always check the return of the "read" methods using this pattern (or something like it).
$query = $this->db->get();
return $query !== FALSE ? $query->result() : NULL;
The main thing is to know that $query isn't FALSE before trying to run a method on it.
For "write" queries simply returning the result of the Query Builder method works, e.g.
return $this->db->insert('mytable', $data);
Naturally, the receiver of this return needs to pay attention.
The next line of code could return any one of the following: TRUE, FALSE, or a CI_DB_result object.
$this->db->query('YOUR QUERY HERE');
The full definition of query() is
DB_driver::query($sql, $binds = FALSE, $return_object = NULL);
Adjust your return checking to the $sql string request.
Once you nail the query statement syntax down future problems are most often related to bad input data. I usually spend more time checking query input data than output. Things like: Is there actually a value here? Is it the correct data type? Is it in the expected range? Garbage in - Garbage out.
Here is the edited script without errors. And the 2 fixes applied to it. To those who helped in part, thank you. To mentions that the code is unclear or messy is inconsequential. Given that most of the following is common structure in mysql queries. Even the example documentation for mysql followed this similar flow. Members who reply should negate from pointless internet banter. Its more worth your time, and my own to do so. Those who stayed on topic and assisted, I thank you.
For example:
$row = mysqli_fetch_row(mysqli_query($con, "SELECT test_table.points FROM test_table WHERE test_table.key = '" . $key . "'"));
if ($row[0] > 0){ // exists
Where $row will return a non-zero result if true. Otherwise 0 on false. There is little need to check mysqli_fetch_row and/or mysqli_query. Since checking $row in simplicity works fine. It is unneeded to check mysqli_fetch_row and/or mysqli_query individually in a general exists condition. It does accurately provide exist / does not exist results. There is no $result $row $query just $row.
The noted deviation to that normal flow was my desire to use call_user_func. And to poll in func and params through $_GET. Will be looking more at PDO. However, the clean code before exec should do alright job for now. Which is to clean before exec.
All in all, the code works just as it should. And have since written more to manage a mysql database. From write, write chunk, read, read chunk, delete, delete chunk.
Also to collect numbered records on request. For example say you have 6 records for the same John Smith. You can now collate and scan for differences in those records. Either for what you want, dont want, etc. Or if say you just want to blindly call the first 3 of those records for John Smith.
mysqli_fetch_row & mysqli_fetch_row fix :
FROM Calling $con outside function then into as per mysql. Which in mysqli does not work as expected. There was no error with the functions, over how $con was being handled.
TO Calling $con inside function with just the added global $con. May end up using $GLOBALS even for this.
Result : Calling $con outside function then in works fine in mysql. In mysqli it requires global be set within the function. ie global $con. Or it fails.
call_user_func non-critical error fix :
FROM call_user_func($func($_GET['user'],$_GET['key'],$_GET['points'],$_GET['type']));
TO call_user_func($func,$_GET['user'],$_GET['key'],$_GET['points'],$_GET['type']);
Result : Both lines execute correctly. From executed with a non-critical error. TO does the same thing, but with no following non-critical error.
Sample Output for both : user=MY_Name;key=34342$ee56i1;points=1234;type=
-- code removed as fixes solved the issues --
You are using call_user_func wrong read the manutal
call_user_func first parameter is the callback - in your case it's a function inside your class so it should be something like this:
If you have a non-static function in an object:
class Test{
public function doit($a){
echo($a);
}
}
$t = new Test();
call_user_func(array($t,'doit'),'asfaasfs');
and in static functions inside object:
class Test{
public static function doit($a){
echo($a);
}
}
call_user_func('Test::doit','asfaasfs');
You have a few problems.
$con is declared outside the class, and is thus not available inside the class. You need to pass it into the class (the better option), or specify it as a global (the quick+dirty option).
mysqli_fetch_row(mysqli_query($con,'...'))
This code is obviously converted directly from your old mysql_xx() code, but it's not great.
You're ignoring any possible error condition that is returned by mysqli_query(). This means that if it fails, it'll pass false into the mysqli_fetch_row() function, which will then fail with a meaningless error expects parameter 1 to be mysqli_result, rather than actually telling you what the error was in the query.
The thing is, because of my first point above, with $con not being set, mysqli_query() is failing, and this is why you're getting the error in mysqli_fetch_row().
Ideally, you should split this code out into multiple lines. Call mysqli_query() on its own, then do some error checking, then call mysqli_fetch_row() only once you know that the query actually worked.
Hope that helps explain what the problems are here. Solve those two points, and you should be well on the way to sorting the whole thing out.
Once you've got rid of those fatal errors, you should also take time to work on the problem that your code is vulnerable to SQL injection attacks. You're currently passing your $_GET variables directly into the query strings without any sanitisation. This will make your system very fragile and easy to hack. You should consider using Parameterised Queries, which is a feature of the mysqli library designed to make it easier to deal with variables in SQL queries in a safe and secure way.
Your class is pointless at the moment, perhaps stick to writing imperative style code as it will at least be cleaner.
At the moment, you should pass $con to your MYsql class to use itself as a resource, not try to access it as a global variable.
Your are not filtering your user's input either, this is dangerous and could lead to SQL injection attacks on your site.
I'd encourage you to read through these two articles, and once you grok them, I'd also encourage you to simply switch to using PDO with prepared statements. This will stop SQL injection attacks that your code currently allows.
http://net.tutsplus.com/tutorials/php/pdo-vs-mysqli-which-should-you-use/
http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
I usually try to minimize calls to MySQL where possible, but I've finally encountered the case where I have to do multiple calls to MySQL in a single script.
It looks like you can't use mysql_fetch_assoc twice in a single script(!).
It seems that mysql_data_seek is the solution, but I cannot seem to get it to work.
To be clear, I have two queries I need to make. The second query depends on results from the first... Here's the structure:
$result = mysql_query($query1);
while($row = mysql_fetch_assoc($result)){
$pos = $row['position'];
}
mysql_free_result($result); // result freed per comment below.
$query2 = ' '; //... dependent on $pos - in mysql shell this returns results!
$result2 = mysql_query($query2)
while($row = mysql_fetch_assoc($result2)){
echo $row['id'];
}
What happens above is that the second while loop returns no results even though the query should have nontrivial rows.
Just to be sure:
Is this how you clear the pointer from the previous result to be able to use mysql_fetch_assoc again?
mysql_data_seek($result,mysql_num_rows($result) - 1);
I'm not sure what to use as the second argument. Admittedly, I am not that clear on pointers, but it seems I should clear the pointer to 0. But I get this error:
Offset 0 is invalid for MySQL result index 8 (or the query data is unbuffered
Check your connection with mysql_error() and see if you're getting the "commands out of sync" error. If so, you need to call mysql_free_result() after completing the first query and before starting the second. You could also just call mysql_close() to close your database connection and then reopen a new one.
For more details, see this question.
OP changed the question, so see the edit
*Deleted the posted codes here**
EDIT
After your edited your question and made clear you have actually 2 resources it looks like there is something else wrong. You don't have to worry about pointer when you use two different resources to supply mysql_fetch_assoc(). The thing with mysql_fetch_assoc() is that it takes your param ($result) by reference.
Now to answer your question:
I usually try to minimize calls to MySQL where possible, but I've finally encountered the case where I have to do multiple calls to MySQL in a single script.
Nothing wrong with multiple SQL calls in one script. Although in general you should try to minimize the SQL calls (because they may hurt performance).
It looks like you can't use mysql_fetch_assoc twice in a single script(!).
Plain wrong. Ofc you can do it. As long as you note the above. However when you have two result sets this wouldn't be your problem.
It seems that mysql_data_seek is the solution, but I cannot seem to get it to work.
Again: this has nothing to do with it when you use two (different) result sets.
To be clear, I have two queries I need to make. The second query depends on results from the first.
This shouldn't be any problem at all. It looks like is something else wrong. Have you verified that the second query really is what you think it is? Are you sure there are records? Are you sure there aren't any (MySQL) errors. Do you have error reporting enabled? Have you tried printing out mysql_error()? To better be able to help you can you please provide your real code and not etc etc stuff? Maybe something else is going on.
Or maybe you are simply trying to run the second query inside the first loop. Which would be bad in so many ways.
I'm having trouble trying to use $stmt->store_result() after executing a prepared statement. The manual says "Transfers a result set from a prepared statement", but to where?
I would ideally like to use it, all nice and buffered in memory, like $mysqli->query() returns.
The PHP documentation examples make it seem like the only good reason to use store_result() is to get the number of rows.
Ideally, I need something that can get the entire result set from a prepared statement and do something like fetch_rows on it. I DID hack the mysqli_stmt class by extending it and adding a fetch_assoc function using some backwards methods, but I would really like to remove that hack if I can get all my data buffered into memory.
So I guess my short question is, I know what store_result() does, but how do you USE it?
(And honestly, I wouldn't even be using $mysqli->prepare() to get a stmt, if it wasn't so damn useful in preventing SQL injection attacks, sterilizing variables, and making my SQL look so nice and pretty with all those question marks.)
The only thing that store_result() does is it moves the result from MySQL into PHP memory. It's not very useful since you still need to fetch the results into PHP variables.
What you are looking for is get_result(). This function will fetch results from MySQL and store them in PHP memory, additionally returning a familiar mysqli_result object.
$stmt = $mysqli->prepare('SELECT ? as col');
$stmt->bind_param('s', $variable);
$stmt->execute();
// returns mysqli_result object
$result = $stmt->get_result();
// loop to get associative rows
foreach ($result as $row) {
echo $row['col'];
}
I am executing a SQL Server stored procedure that is supposed to return an output parameter (ErrCode), as well as a resultset.
I am calling the procedure from PHP using the following code, but so far have been unable to retrieve the output parameter:
$stmt = mssql_init("addFaculty", $this->db);
mssql_bind($stmt, "#FacultyID", $FacultyID, SQLCHAR);
...imagine other parameters here...
mssql_bind($stmt, "#ErrCode", &$ErrCode, SQLINT1, TRUE, FALSE, 1);
$result = mssql_execute($stmt);
echo $ErrCode
$ErrCode is always echoed as 0, even when it should return a '1' or '2'. When I execute the procedure within SQL Server Studio, however, the 'Messages' tab will correctly display a '1' or a '2'.
In doing research, I found one suggestion that stated you must use mssql_next_result() first to be able to access the output parameters. I tried this, but it simply returned a PHP
"Warning: mssql_next_result(): supplied argument is not a valid MS SQL_result resource"
I also found a reference to a similar issue in this thread but did not see a real resolution.
Like the person in that thread, I am using Linux (CentOS) with PHP5 and MS SQL Server 2005.
Does anyone have any suggestions on this? I had an issue like this in a previous project as well, and in the end, simply gave up on using output parameters (and did all my error_checking in the PHP instead) because I couldn't figure it out. It would be nice to find an answer :(
I am not a PHP guy, but I think this will help.
It says:
Note that when retrieving an output or
input/output parameter, all results
returned by the stored procedure must
be consumed before the returned
parameter value is accessible.
EDIT:
Have you tried ADODB
Check my post on this problem, I used a class extended from Zend_Db_Table_Abstract. I do not use pure PHP, still using the framework accordingly. Seens to be fine and run ok, I am even getting also the resultset back! Hope it helps:
Execute MSSQL stored procedure via Zend Framework