I am doing a select in my Oracle database and need to take different actions for the result being false (contains no results) or being true (contains one or more results).
However testing the result in the following way gives me a problem. In the cases where I actually have results from my query the if(! naturally validates to false and moves on to the else statement - perfect!
But when doing this test the internal pointer moves in the result and thereby the first result is lost when performing the while statement later.
if (!($row = oci_fetch_array($get_doc_paths, OCI_ASSOC+OCI_RETURN_NULLS))){
do something
}
else {
while ($row = oci_fetch_array($get_doc_paths, OCI_ASSOC+OCI_RETURN_NULLS)){
do something with $row
}
}
How do I test if there are results without moving the internal pointer?
In MySQL I would have used the mysqli_num_rows or simply just reset the pointer. I can't find a way to do this with Oracle.
$status = false;
while($row = oci_fetch_array(...)) {
$status = true;
// Do something with row
}
if(!$status) {
// Do something else
}
Related
IF I use the !empty() on an sql query it doesn't say it is empty even if no rows are returned. e.g.
$result = $conn->query($sql_ideas);
if ( !empty($result)) {
while($row = $result->fetch_assoc()) {
$highlights[] = array($row["summary"], $row["detail"]);
}
-- Do stuff --
}
It just carries on as though a result is returned. Am I doing something wrong or is there a way to fix this?
Assuming you're using mysqli, your result object will actually be a 'mysqli result' - a class in it's own right. Checking that the row count is greater than zero is going to be the way to go.
http://php.net/manual/en/mysqli-result.num-rows.php
So, here's my issue: I have a function that queries sql and pulls it into a resource. In this function, I run:
if (odbc_num_rows($rs) === 0) {
return FALSE;
} else {
if ($type !== "Issues") {
while (odbc_fetch_row($rs)) {
$issues['tvi'][] = odbc_result($rs, 'TitleVolumeIssue_c_');
}
}
return $rs;
}
This does exactly what it is supposed to do. However, when I pass $rs into the next method for parsing into html, it seems as though $rs gets unset. Oddly, I can call odbc_num_rows($rs) and it gives me the correct number of rows, but dumping the var shows it is false and I can't loop through the resource to get any values.
How can I either free up that resource so that it can be used in the next function or how can I rewrite the IF condition so that I get the values without unsetting the resource?
Each time you fetch it moves the database cursor to the next row.
So odbc_fetch_row() keeps going to the next row, until the last one. After that it returns false.
Unfortunately you cannot move the row pointer back to the first record.
You will have to query your DB one more time.
Another option for this would be to store the odbc result in an array that you can loop through using a foreach. This preserves the data and you only have to query once vs multiple times (helps when dealing with a lot of data).
while($row = odbc_fetch_array($rs)) {
$resultsArray[] = $row;
}
Then loop through it like this...
foreach ($resultsArray as $key=>$value){
//Do what you need to do...
}
I had a similar problem in my question here and #Jeff Puckett was able to explain it pretty well.
This works well, except that the last row always returns false. I've use this multiple times within my site and no matter what query I run, the last row always returns false instead of the data in the last row.
So if I have a query that should return 2 rows, it returns 1 row and false. I'm not really sure why.
function query2array($query, $sql_con) {
$result = mysql_query($query,$sql_con);
if(!$result) {
return false;
}
else if (mysql_num_rows($result) > 0) {
//set entire result to array
while($arr_data[] = mysql_fetch_array($result));
var_dump($arr_data);
if(count($arr_data) > 0) {
return $arr_data;
}
}
return false;
}
I'm new to PHP and I've read the documentation on mysql_fetch_array and just can't seem to figure out what's going wrong here. (I also know that I should be using mysqli, but I picked up on a site developed by someone else)
Try this:
while($row = mysql_fetch_array($result))$arr_data[] = $row;
The reason of such behaviour is you appending mysql_fetch_array() result to array without checking if it successfully retrieved.
As of manual:
Returns an array of strings that corresponds to the fetched row, or
FALSE if there are no more rows.
NOTICE: MySQL (mysql*_ functions) extension is deprecated. I suggest to use MySQLi (mysqli*_ functions) or PDO instead.
Here is a simple scenario I am contemplating. I have a query that is executed on a MySQL database from PHP. I would like to check if any data was returned from the query. However, in order to perform that check, it pulls out one of the rows of returned data.
Look at this example, and its comments:
$booksGrabber = ("SELECT * FROM table");
if (!$booksGrabber) {
//Query failed, perhaps a syntax error
exit;
}
if (!mysql_result($booksGrabber, 0)) {
//No data was returned :(
exit;
}
while ($book = mysql_fetch_assoc($booksGrabber)) {
//mysql_result() stole the first row of returned data
//So if I was expecting the loop to display 4 results,
//I only get 3...
}
How can I check if data was returned from the database without running two queries (one to check, the other to display all of the data) or having one of the rows stolen?
Use mysql_num_rows. It was as simple as it looked.
EDIT: If you want more complicated, add mysql_data_seek($booksGrabber,0).
Simple: mysql_query() function that runs the query will return false on error and then you can use mysql_num_rows() for the count. So you can do something like:
$result = mysql_query('SELECT * FROM table');
if (!$result) {
print('Invalid query: ' . mysql_error());
} elseif (mysql_num_rows() == 0) {
print("no results");
} else {
// You can use safely data from the query :)
}
I'm just getting started on writing functions instead of writing everything inline. Is this how a reusable function is typically written?
function test_user($user) {
$conn = get_db_conn();
$res = mysql_query("SELECT * FROM users WHERE uid = $user");
$row = mysql_fetch_assoc($res);
if (count($row) == 1) {
return true;
}
else {
return false;
}
}
When someone logs in, I have their UID. I want to see if that's in the DB already. It's basic logic will be used in a
"If exists, display preferences, if !exists, display signup box" sort of flow. Obviously it's dependent on how it's used in the rest of the code, but will this work as advertised and have I fallen for any pitfalls? Thanks!
Try this:
$conn = get_db_conn(); # should reuse a connection if it exists
# Have MySQL count the rows, instead of fetching a list (also prevent injection)
$res = mysql_query(sprintf("SELECT COUNT(*) FROM users WHERE uid=%d", $user));
# if the query fails
if (!$res) return false;
# explode the result
list($count) = mysql_fetch_row($res);
return ($count === '1');
Thoughts:
You'll want better handling of a failed query, since return false means the user doesn't already exist.
Use the database to count, it'll be faster.
I'm assuming uid is an integer in the sprintf statement. This is now safe for user input.
If you have an if statement that looks like if (something) { true } else { false } you should collapse it to just return something.
HTH
That is reuseable, yes. You may want to consider moving the SQL out of the PHP code itself.
Although you weren't asking for optimization necessarily, you might want to consider querying for the user's display preferences (which I assume are stored in the DB) and if it comes back empty, display the signup box. You'll save a trip to the database and depending on your traffic, that could be huge. If you decide to keep this implementation, I would suggest only selecting one column from the database in your SELECT. As long as you don't care about the data, there's no reason to fetch every single column.
First off, you need to call
$user = mysql_real_escape_string($user);
because there's an sql injection bug in your code, see the manual. Second, you can simplify your logic by changing your query to:
SELECT COUNT(1) FROM user WHERE uid = $user;
which just lets you evaluate a single return value from $row. Last thing, once you have the basics of php down, consider looking at a php framework. They can cause you trouble and won't make you write good code, but they likely will save you a lot of work.
Indent!
Overall it looks not bad...check the comments..
function test_user($user)
{
$conn = get_db_conn(); //this should be done only once. Maybe somewhere else...?
$res = mysql_query("SELECT uid FROM users WHERE uid = $user");
$row = mysql_fetch_assoc($res);
//I can't remember...can you return count($row) and have that forced to boolean ala C? It would reduce lines of code and make it easier to read.
if (count($row) == 1) {
return true;
}
else {
return false;
}
}
Also,
if (condition) {
return true;
}
else {
return false;
}
can be rewritten as:
return condition;
which saves quite a bit of typing and reading :)