Is it bad to put a Query inside an while loop? - php

I built a Query inside an While loop to get the status from my users. Is there any problem by doing that?
I would like to do it in a different way.
My code.
$output = array();
while($row = mysqli_fetch_assoc($result))
{
if ($row['user_id'] != $id)
{
$checkstatus= mysqli_query($con,"SELECT session_id, status FROM frei_session WHERE session_id = '".$row['user_id']."' ");
$status = mysqli_fetch_row($checkstatus);
if(!$status[0]){
$row['status'] = 0;
}
$output[] = $row;
}
}
$json = json_encode(array("contacts" => $output ));
print($json);
Thank you.

It will blow up your code and can result in very bad performance, escpecially when your main query is returning a lot of rows. A SQL-Server can connect different tables much more efficient by using Joins. For me it seems like a good scenario to use them here. Especially the LEFT-JOIN can be usefull to load a session. It will return NULL for the requested fields when there is no session connected with the current user.
But because I don't even know your main query or much less the use behind your code, you've to decide whether a user without a session makes sense in your case. If not, use a EQUAL-JOIN instead. Then your query wouldn't return any data if no session exists.
An example how can such a JOIN can look when you've two tables USER and SESSION:
SELECT user.username, user.email,
session.status AS session_status
FROM user, session
WHERE user.userid = 123
AND session.session_id = user.user_id

I don't see any problem with having a query like yours inside the while loop. It would become problematic if the query was inefficient (imagine if the query would return 10 lines and you would only use/need 1), but you are targeting your user in the where clause, so it's OK.

Related

Sum variables in an array using while loop only 1 iteration per refresh PHP SQL

Hello stackoverflow, long time lurker first time asker. Anyways I am creating a project for my school and it is almost completely finished but I think I need help with the while loop. I am trying to sum the variables that are stored in the array and then output that into a useable variable that I can sum with another variable. The problem is the loop only does 1 iteration every time I refresh to page. So it will eventually get the full array but only one item at a time. Please let me know what I am going wrong, I'm sure its something dumb!
$bill= mysql_query("SELECT Transaction.date, Transaction.Price, Transaction.customer_customer_id, Service.cost, Service.user_id, Service.uname
FROM *.Transaction,*.Service
WHERE Transaction.customer_customer_id = Service.user_id AND Service.uname = '$uuname'");
$query_row=mysql_fetch_array($bill);
$userservice = ($query_row[cost]);
$userprice = ($query_row[Price]);
$row2=array();
while($row = mysql_fetch_array($bill))
{
$row2[] += $row['cost'];
}
$totalservice = array_sum($row2);
Thanks for any help you guys may have. This one is frying my brain.
Both your SQL and your PHP make no sense.
FROM *.Transaction,*.Service
...will throw an error in MySQL, but your code doesn't check for errors. I suspect it should be:
FROM Transaction, Service
While the PHP will parse and run.....
while($row = mysql_fetch_array($bill)) {
$row2[] += $row['cost'];
}
$totalservice = array_sum($row2);
Is a very strange way to populate an array. Why not just....
while($row = mysql_fetch_array($bill)) {
$totalservice+=$row['cost'];
}
Indeed, if you are just throwing away the rest of the data, then why are you fetching it from the database?
SELECT SUM(Service.cost)
FROM Transaction,Service
WHERE Transaction.customer_customer_id = Service.user_id
AND Service.uname = '$uuname'
In which case the join is also redundant:
SELECT SUM(Service.cost)
FROM Service
WHERE Service.uname = '$uuname'
Rewrite query as
SELECT Service.user_id, Service.uname, SUM(Service.cost) as cost
FROM djqrico_hotel.Transaction LEFT JOIN djqrico_hotel.Service ON Transaction.customer_customer_id = Service.user_id
WHERE Service.uname = '$uuname' GROUP BY Service.user_id
if you want to get sum of all user's transactions.
The problem is the loop only does 1 iteration every time I refresh to page.
Have you ran the query against the database and checked if it's returning more than one row?
Also, if all you want to do is sum the cost column you could do that in sql:
SELECT SUM(cost)[....]

mysql - strange thing with update and select statements

I have a strange mysql-thing going on here, it is about the following code:
$res = mysql_query("SELECT * FROM users WHERE group='".$group."'");
if (mysql_num_rows($res)==1) {
$row = mysql_fetch_assoc($res);
$uid = $row['uid'];
$user_update = mysql_query("UPDATE fe_users SET group = 5 WHERE group='".$group."'");
return 'ok';
} else {
return 'not ok';
}
I am checking, if there is a user with the group = $group. If so, the group is updated to 5 and after that the string "ok" is returned, if no user with group=$group exists, as you can see the string "not ok" is returned.
This should be very easy, but the problem now is, that if there is a user with group=$group, the update is done correctly, but instead of returning "ok", php returns "not ok", as if the change from the update is been taken into account for the above executed select retroactively. I dont understand this. Any help would be really appreciated.
Thanx in advance,
Jayden
I think 'group' is a reserved keyword that you have used as a field name, change it or use like
$res = mysql_query("SELECT * FROM users WHERE `group`='".$group."'");
and
$user_update = mysql_query("UPDATE fe_users SET `group` = 5 WHERE `group`='".$group."'");
and you can use count($res)==1 instead of mysql_num_rows($res)==1 if it is a problem.
Reference: Mysql Reserved keywords.
I am not sure if this has any merit but try using this style in your SELECT and UPDATE commands: WHERE group='$group', without using string joins. Other than that I can't seem to see why you are getting an update and not being returned "ok".
You are checking if mysql_num_rows($res)==1, so you'll return ok if there is exactly one user on that group. If there are two or more users, it will return not ok. Probably not what you want, right? I think you should check if mysql_num_rows($res)>=1.
You might consider modifying the placement of your brackets, and changing your num_rows check, like so:
$res = mysqli_query("SELECT uid FROM users WHERE `group` ='".$group."'");
if (mysqli_num_rows($res)>0) {//there was a result
while($row = mysqli_fetch_assoc($res)){
// grab the user id from the row
$uid = $row['uid'];
// and update their record
$user_update = mysqli_query("UPDATE fe_users SET `group` = 5 WHERE `group`='".$group."'");
if(mysqli_num_rows($user_update)==1){
return 'ok, updated user';
} else {
// database error
return 'not ok, unable to update user record';
}
}//end while row
}else{
return 'No results were found for this group.';
}
By selecting just the column you want, you reduce the query's overhead. By comparing the initial result to 0 instead of 1, you allow for groups with many members. By wrapping the update function in a while loop, you can loop through all the returned results, and update records for each one. By moving the test that returns 'ok'/'not ok' to check for success on the update operation, you're able to isolate database errors. The final else statement tells you if no update operation was performed because there are no members of the group.
BTW, for future-compatible code, I recommend using mysqli, as the "mysql_query" family of PHP functions are officially deprecated. See http://www.php.net/manual/en/mysqli.query.php for a quick start, it's largely the same thing.

Query for select multiple values from 2 tables

Table names:
tbla_can_types
Fields are fac_id,type_id,type_name,status
tbla_canteen_rates (there is no data in this table)
Fields are `fac_id,cat_id,type_id,from time,to_time,rate,off_rate,status,effective_date.,can_id(sequence number)
<?php
include('adodb/adodb.inc.php');
$conn=&ADONewconnection('oci8');
$conn->Pconnect('conn','hostname','username','pwd');
$fac_id=$_GET['fac_id'];
$cat_id=$_GET['cat_id'];
$file=fopen("text.txt","w+");
global $newId;
header("Content-type: text/xml");
echo('<?xml version="1.0" encoding="iso-8859-1"?>');
echo "<data>";
$ids = explode(",",$_POST["ids"]);
$rates="select type_id,from_time,to_time,rate,off_rate,status,to_char(effective_date,'dd-Mon-yyyy') e_date,can_id from tbla_canteen_rates where fac_id=$fac_id and cat_id=$cat_id order by to_number(substr(from_time,0,length(from_time)-3))";
$rs1=$conn->Execute($rates);
if(!$rs1->EOF)
echo $rs1->fields[0].'~'.$rs1->fields[1].'~'.$rs1->fields[2].'~'.$rs1->fields[3].'~'.$rs1->fields[4].'~'.$rs1->fields[5].'~'.$rs1->fields[6].'~'.$rs1->fields[7];
$temp_id=$rs1->fields[0];
echo $temp_id;
$rs1->MoveNext();
for ($i=0; $i < sizeof($ids); $i++)
{
$rowId = $ids[$i]; //id or row which was updated
$newId = $rowId; //will be used for insert operation
$mode = $_POST[$rowId."_!nativeeditor_status"]; //get request mode
switch($mode)
{
case "inserted":
$insert= "insert into tbla_canteen_rates(type_id,from_time,to_time,rate,off_rate,status,effective_date,fac_id,cat_id )values
($temp_id,
'".$_POST[$rowId."_c1"]."',
'".$_POST[$rowId."_c2"]."',
'".$_POST[$rowId."_c3"]."',
'".$_POST[$rowId."_c4"]."',
'".$_POST[$rowId."_c5"]."',to_date('".$_POST[$rowId."_c6"]."','dd-Mon-yyyy'),$fac_id,$cat_id)";
$conn->Execute($insert);
fwrite($file,$insert);
$action='add_row($rowId)';
break;
case "deleted":
$delete = "delete from tbla_canteen_rates where can_id=".$rowId ;
$conn->Execute($delete);
fwrite($file,$delete);
$action ='delete_row($rowId)';
break;
default:
$update ="update tbla_canteen_rates set
type_id=$temp_id,
from_time='".$_POST[$rowId."_c1"]."',
to_time='".$_POST[$rowId."_c2"]."',
rate='".$_POST[$rowId."_c3"]."',
off_rate='".$_POST[$rowId."_c4"]."',
status='".$_POST[$rowId."_c5"]."',
effective_date=to_date('".$_POST[$rowId."_c6"]."','dd-Mon-yyyy'),
fac_id='$fac_id',cat_id='$cat_id'
where can_id=".$rowId;
$conn->Execute($update);
fwrite($file,$update);
$action = 'update_row($rowId)';
break;
}
echo "<action type='".$action."' sid='".$rowId."' tid='".$newId."'/>";
}
echo "</data>";
?>
In the query i need id for type_id in a variable
i have written but every time it is getting id of first element only.
in this i need an id for type_id.
please send me the code 4 that
Regards
Pawan
I've got a sneaking suspicion that you've got several questions in there, but since you asked about the sql query, this should work:
Note: I'm assuming fac_id is the id that binds the two tables together. "var_fac_id" and "var_cat_id" are the values from your comboboxes.
Select t1.type_name, t2.from_time, t2.to_time, t2.rate
FROM tbla_can_types as t1 LEFT JOIN tbla_canteen_rates as t2
ON t1.fac_id = t2.fac_id
WHERE t1.fac_id = var_fac_id AND t2.cat_id = var_cat_id
Further notes: I think this should work despite the "AND t2.cat_id = var_cat_id" (which obviously would find not results in an empty table), since it's a left join. If it returns an empty set, however, see if it works if you remove it.
Update:
your comment above makes me think the tables are bound together by type_id instead. If that's the case, use ON t1.type_id = t2.type_id instead of ON t1.fac_id = t2.fac_id
Update #2 based on poster's comments
I'm not going to do your homework, dude. And homework is the only place where they'd tell you to not do joins. I will send you to some resources that will help you learn this stuff, though. Check out the basic mysql example from php.net: http://www.php.net/manual/en/mysql.examples-basic.php . That sample actually gets you pretty close to what you need. Also their overall mysql documentation, which is good for looking up what specific functions do: http://www.php.net/manual/en/book.mysql.php . Finally, remember that you're learning two languages here -- PHP, along with its functions to access a mysql DB, and -- SQL, which is a query language used within DBs. For SQL, check out http://sqlzoo.net/ , which seems a decent introduction on how to write queries.
Good luck on your assignment.

How do I show a user's credit based on their session

I'm developing a simple LAMP app where users can credit their account using Paypal. I suspect this is a simple issue, but have spent quite a while experimenting to no avail and would appreciate any thoughts:
System has a user management system working fine using sessions, but I can't get it to display the current user's credit.
But I've been trying things along the lines of:
$result = mysql_query("
SELECT *
FROM users
INNER JOIN account
ON account.UserID=account.UserID
ORDER BY account.accountID");
while($_SESSION['Username'] = $row['Username'] )
{
echo $row['Username'];
echo $row['Credit'];
}
I suspect the while statement is invalid, but I want it to echo username and credit where the current session username = the username stored in the database.
Thanks so much for taking a look - very much appreciated.
Okay there is actually a lot wrong with your code that can not be fixed by you as you have obviously no knowledge of php at all.
But let me explain this so you can get a good understanding of what you did wrong:
First of all, your mysql statement is just wrong.
Why do you join a field on itself? You won't get the corresponding users <-> account rows because users is never actually joined.
In addition to that, if you want to fetch a single row (you only want one because you only want to echo the data of one user, fetching more is only heavier in resources), tell mysql to do that. A simple example would be "WHERE a="b" LIMIT 1 (select only row where a is equal to "b", return after finding the first).
Now, to read something from your query, you need to fetch the corresponding data.
You can do that by using mysql_fetch_assoc / mysql_fetch_array / mysql_fetch_object.
This would look something like this: $data = mysql_fetch_array($query);.
In this case, you don't need to use a while() loop as you only have one row. A while loop is only necessary if you want to work with more then one row.
The rest of your code would be correct, though you don't need to call echo twice. You can simply connect both variables with a ".": echo $row['Username'].$row['Credit'];.
If you want to insert a space in between, connect it with another dot: echo $row['Username']." ".$row['Credit'];.
while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
if ($row['Username'] == $_SESSION['Username'])
{
echo $row['Username'];
echo $row['Credit'];
break; // I believe username is unuque.
}
}
But it's much better to get just 1 row from the table :
$result = mysql_query("
SELECT *
FROM users
INNER JOIN account
ON account.UserID=users.UserID
WHERE Username ='".mysql_real_escape_string($_SESSION['Username'])."'" );
if ($result && $row = mysql_fetch_array($result, MYSQL_ASSOC))
{
echo .....
}
You only have a mysql result, now you have to return that information as an associative array (or object)
while ($row = mysql_fetch_assoc($result)) {
if ($_SESSION['username'] == $row['Username']) {
echo $row['Username'];
echo $row['Credit'];
}
}
It appears as if you are using $_SESSION['username'] as a way to check user authentication on the site, much better to use a salted+hashed version of the username and possibly the login time (never include the password).
One thing that jumps out at me is that your query is joining on:
account.UserID=account.UserID
instead of:
account.UserID=user.ID
Also, this is not right:
while($_SESSION['Username'] = $row['Username'] )
The = sign is for assignment, not comparison, so you're actually setting the value of $_SESSION['Username'] to $row['Username']. Then, the expression is evaluated as a boolean (since it's within a while conditional), and if it's true once, it'll be true forever. Infinite loop city.

PHP get result string from PostgreSQL Query

I'm new to PHP and SQL, but I need a way to store the result of an SQL Query into a variable.
The query is like this:
$q = "SELECT type FROM users WHERE username='foo user'";
$result = pg_query($q);
The query will only return one string; the user's account type, and I just need to store that in a variable so I can check to see if the user has permission to view a page.
I know I could probably just do this query:
"SELECT * FROM users WHERE username='foo user' and type='admin'";
if(pg_num_rows($result) == 1) {
//...
}
But it seems like a bad practice to me.
Either way, it would be good to know how to store it as a variable for future reference.
You can pass the result to pg_fetch_assoc() and then store the value, or did you want to get the value without the extra step?
$result = pg_query($q);
$row = pg_fetch_assoc($result);
$account_type = $row['type'];
Is that what you are looking for?
Use pg_fetch_result:
$result = pg_query($q);
$account_type = pg_fetch_result($result, 0, 0);
But on the other hand it's always good idea to check if you got any results so I'll keep the pg_num_rows check.

Categories