multi query select using wrong array? - php

I have a multi query select which half works. The first query is straight forward.
$sql = "SELECT riskAudDate, riskClientId, RiskNewId FROM tblriskregister ORDER BY riskId DESC LIMIT 1;";
The second one doesn't seem to work even when I do it on its own:
$sql ="SELECT LAST(riskFacility) FROM tbleClients";
If I get rid of the LAST it returns the first entry in that field of the table. I want to use the LAST to get the LAST entry in that field.
When I do the first query on its own I get the data returned and I can echo it to the screen. When I add the second (with out the LAST) I get nothing. Here is what I am using
$result = $conn->query($sql);
if ($result == TRUE){
$r = $result->fetch_array(MYSQLI_ASSOC);
echo $r['riskAudDate'];
echo $r['riskClientId'];
echo $r['RiskNewId'];
echo $r['riskFacility'];
echo "<pre>";
print_r($r);
echo "</pre>";
}
The last bit is just for me to see whats in the array and just for testing.
So I have worked out that its the results array that is not right.
If I change the actual query to multi query I get this:
Call to a member function fetch_array() on boolean
So the array bit seems to be wrong for a multi query. The data returned is one row from each table. It works for the top query but add in the second (which I'm not sure is correct anyway) and the whole things crashes. So I guess it's a two part question. Whats wrong with my inserts and whats wrong with my returned array?

There is no last() function in mysql, it is only supported in ms access, if I'm not much mistaken. In mysql you can do what you do in the 1st query: do an order by and limit the results to 1.
According to the error message, the $conn->query($sql) returns a boolean value (probably true), therefore you cannot call $result->fetch_array(MYSQLI_ASSOC) on it. Since we have no idea what exactly you have in $sql variable, al I can say is that you need to debug your code to detrmine why $conn->query($sql) returns a boolean value.
Although it is not that clear from mysqli_query()'s documentation, but it only supports the execution of 1 query at a time. To execute multiple queries in one go, use mysqli_multi_query() (you can call this one in OO mode as well, see documentation). However, for security reasons I would rather call mysqli_query() twice separately. It is more difficult to execute a successful sql injection attack, if you cannot execute multiple queries.

It seems to me you are trying to do two SQL-queries at once.
That is not possible. Do a separate
$result = $conn->query($sql);
if ($result == TRUE){
while( $r = $result->fetch_array(MYSQLI_ASSOC)) {
...
}
}
for each SQL-query.
concerning :
$sql ="SELECT LAST(riskFacility) FROM tbleClients";
since the last function does not exists in MySQL i would recommend doing a sort like this(because i don't know what you mean with last )
$sql ="SELECT riskFacility FROM tbleClients order by riskFacility desc limit 0,1";

Related

PHP / mysqli: Prepared Statements with num_rows constantly returning nothing

In my test-surroundings there is a database containing some Person Information (Name, E-Mail, Adress etc.). These Informations can be inserted by anyone into the database via a form. In the background they are inserted with a parameterized INSERT into the database after submission.
What I now would like to do is to detect if some person tries to insert the same values into the database again, and if he does, not inserting the new values and instead showing an error message. (So every person name in the database is unique, there are no multiple rows linked to one name).
I had a numerous number of ideas on how to accomplish this. My first one was to use a query like REPLACE or INSERT IGNORE, but this method would not give me feedback so I can display the error message.
My second attempt was to first do a SELECT-query, checking if the row already exists, and if num_rows is greater than 0, exit with the error message (and else do the INSERT-part). For this to work I will have to use parameterized queries for the SELECT too, as I´m putting some user input into it. Figuring that parameterized queries need special functions for everything you could normally do with way less lines of code, I researched in the internet on how to get num_rows from my $statement parameterized-statement-object. This is what I had in the end:
$connection = new mysqli('x', 'x', 'x', 'x');
if (mysqli_connect_error()) {
die("Connect Error");
}
$connection->set_charset("UTF-8");
$statement = $connection->stmt_init();
$statement = $connection->prepare('SELECT Name FROM test WHERE Name LIKE ?');
flags = "s";
$statement->bind_param($flags, $_POST["person_name"]);
$statement->execute();
$statement->store_result();
$result = $statement->get_result(); //Produces error
if ($result->num_rows >= 1) {
$output = "Your already registered";
} else {
$output = "Registering you...";
}
exit($output);
After all, I can´t get why mysqli still won´t give me num_rows from my statement. Any help is appreciated, thanks in advance!
Oh, and if you guys could explain to me what I have to do to get affected_rows,that would be awesome!
EDIT: I know I could to this by using unique constraints. I also found out that I can find out if INSERT IGNORE skipped the INSERT or not. But that won´t answer my complete question: Why does the SELECT num_rows alternative not work?
ANOTHER EDIT: I changed the code snippet to what I now have. Although my mysql(i)-version seems to be 5.6.33 (I echo´d it via $connection->server_info) get_result() produces the following error message:
Fatal error: Call to undefined method mysqli_stmt::get_result() in X on line X (line of get_result)
The behaviour of mysqli_num_rows() depends on whether buffered or unbuffered result sets are being used. For unbuffered result sets, mysqli_num_rows() will not return the correct number of rows until all the rows in the result have been retrieved. Note that if the number of rows is greater than PHP_INT_MAX, the number will be returned as a string.
Also make sure that you declare ->store_result() first. Moreover the function doesn't work with LIMIT used jointly with SQL_CALC_FOUND_ROWS. If you want to obtain the total rows found you must do it manually.
EDIT:
If nothing from the suggestions does not work for you, then I would propose to rewrite your SQL query:
SELECT `Name`, (SELECT COUNT(*) FROM `Persons`) AS `num_rows` FROM `Persons` WHERE `Name` LIKE ?
This query will return the total number from your Persons table, as well as Name, if exist.

Error accessing MySQL database with PHP object (nested queries)

I want to get some data from a Sphinx server and pass it to MySQL to execute some queries. I'm new to PHP so probably I'm missing something here. I've looked for similar questions but can't find anything so maybe you can help me.
The error is in the first while. I'm pretty sure it's due to the $rown variable but don't know the reason. (I've verified that I can retrieve data from the connections so it is passing the data where the error lies - could be the sql syntax of the query but that seems fine).
Edited the code thanks to the comments below, now I get the error: Warning: mysqli_fetch_object() expects parameter 1 to be mysqli_result, boolean given in C:\Apache24\htdocs\test3.php on line 20. This is because the query failed, I still suspect it is because $rown.
$sphinxcon = mysqli_connect...
$mysqlcon = mysqli_connect...
$query = "SELECT names FROM iproducts LIMIT 0,1000";
$raw_results= mysqli_query($sphinxcon, $query);
//Until here works ok, now I want to pass $raw_results to MySQL
while ($row = mysqli_fetch_object($raw_results)) {
$rown = $row->names;
$mquery = "SELECT text FROM claims WHERE EXISTS ($rown) LIMIT 0,1000";
$mysqlresults = mysqli_query($mysqlcon, $mquery);
while ($final = mysqli_fetch_object($mysqlresults)) //this is line 20
{
printf ("%s<br />", $final->text);
}
}
Thanks :)
Well $row contains an object, so would have to use it as such, maybe
$rown = (string)$row->names;
... assuming you want the variable to contain the 'names' attribute you just SELECTed from Sphinx index.
As for the mysql EXISTS(), no idea what you really doing here, seems confused. How you structured it currently suggests that 'names' attribute in sphinx contains a complete SELECT query, that mysql could execute for the exists condition. That seems unlikely.
Guessing you meaning to more normal query something like
$mquery = "SELECT text FROM claims WHERE text LIKE '%$rown%' LIMIT 0,1000";
But that is subject to SQL injection, particully if names might contain single quotes. SO should escape it. Perhaps
$rown = mysqli_real_escape_string($mysqlcon, $row->names);
But might be worth reading up on prepared queries.
btw, the 'Error' you getting, is because you creating an invalid query and not dealing with it. So $mysqlresults is FALSE.
$mysqlresults = mysqli_query($mysqlcon, $mquery) or die("Mysql Error: ".mysqli_error($link)."\n");

How to get row count & loop through the result set

I've recently gotten over my bad habit of using the deprecated mysql functions in favor of mysqli, and I'm having some issues.
Right now, I'm using something similar to the following:
$query = $conn->prepare("SELECT * FROM table WHERE cid = ?");
$query->bind_param('i', $id);
$query->execute();
And this is where I get stuck. In order to loop through the result, I use:
while ($row = $query->get_result()->fetch_assoc()) {
//My code here
}
However, I need to determine the number of rows returned from the query before going through the results. To do this, I need to do the following:
$query->store_result();
$rows = $query->num_rows;
But I get errors when calling both get_result and store_result on the same query.. is there an easier way to do this? Am I overthinking things? I basically just want to determine if the result set has greater than x # of rows, and if so, loop through the results.
Thanks for any help.

SQL Sanitization Output/Datatype Error

I'm attempting to sanitize the input of some PHP/SQL code, but I keep receiving the following error when checking the number of rows:
mysqli_num_rows() expects parameter 1 to be mysqli_result
It feels like I'm missing a method to convert/handle the query after execution, and there is little in the documentation to bridge this gap. Assuming $conn is a properly connected mysqli database call, here is my code:
$qry = mysqli_prepare($conn,'SELECT * FROM table WHERE attribute=?');
mysqli_stmt_bind_param($qry,'s',$_SESSION['string']);
mysqli_stmt_execute($qry);
/* Should something go here? */
if(mysqli_num_rows($qry) > 0)
{
//foo
}
I avoided object notation because it wasn't working either - this simply appeared a little more explicit, but I'm not opposed to either method.
Looking forward to hearing any thoughts - thank you in advance!
I don't use mysqli very often, but I believe the issue stems from the fact you are trying to call the mysqli_num_rows() method against a sql string. After running the execute command, pull the results of the execution into a variable and pass that into your mysqli_num_rows() call.
// Added this to capture the results of the execution
$result = mysqli_stmt_get_result($qry);
if(mysqli_num_rows($result) > 0)
{
//foo
}
Okay, so I was able to discover a way to count the number of rows and retrieve the db output:
$stmt = mysqli_prepare($conn, 'SELECT blah FROM table WHERE attribute=?');
mysqli_stmt_bind_param($stmt,'s',$string);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
mysqli_stmt_bind_result($stmt,$bindingvar);
mysqli_stmt_fetch($stmt);
if(mysqli_stmt_num_rows($stmt) > 0) {
//foo
}
And output is now assigned to $bindingvar.
It's cumbersome, but it does everything I want it to, and it's nice and procedural.
It should be noted this method doesn't work well for more than one result from a database, but given the level of problems with "get_result()" this is far better than nothing.
Hope this helps!
- M

How do I use a MySQL user-defined function from within PHP?

Spent several hours searching for an answer without success. I've written a user-defined function in MySQL which is passed an identifier which it uses to retrieve various pieces of data, concatenate it into one string and return it. I want to call this function from my PHP page and output the result.
Unsuccessful attempts include:
1. $result = mysql_query("select functionName($id)");
2. $sql = "select functionName($id)";
$result = mysql_query($sql, $link);
3. functionName($id)
Any ideas?
1 and 2 are close, but $result is not going to contain the result of the function call. Rather, it is going to contain the result cookie from the query. You can use that cookie to get the actual data, with mysql_fetch_row(). The function call just returns a value for the select statement, just the same as "SELECT 42" or "SELECT a FROM MyTable". So to get the result you would use the same mechanism as with any other SQL query that returns results; that is, use the cookie and call mysql_fetch_row(). So your final code will look like this:
$result = mysql_query("select functionName($id)");
$row = mysql_fetch_row($result, $link);
$returnValue = $row[0];
Note that you don't want to be interpolating variables directly into an SQL string (that can be a vector for attacks). I assume, however, that this code is just for example purposes.
I had the same question and found this very useful write up from devx, particulary the part at the bottom about calling MySQL functions:
http://www.devx.com/webdev/Article/42887/0/page/2
With regards to mysqli, my code is now as follows:
$result = mysqli_query($sqlconnection,"SELECT functionName($id)");
$row = mysqli_fetch_row($result);
return $row[0];
works perfectly.

Categories