I have two tables in a database. In reports I am storing info for reports and in report_roles I am assigning which user can access the report.
reports
+--+-----------+---------------+
|id|report_name|report_filename|
+--+-----------+---------------+
|13|Report 1 |reportname1 |
|14|Report 2 |reportname2 |
|15|Report 3 |reportname3 |
+--+-----------+---------------+
report_roles
+---------+-------+
|report_id|user_id|
+---------+-------+
|14 |1 |
|13 |1 |
|14 |2 |
|13 |2 |
+---------+-------+
I want to display all the reports from table reports with checkboxes and check only those which are added in the report_roles associated with the user id. This is the code I am running:
$id = $_POST['user_id'];
$query = "SELECT * FROM reports LEFT JOIN report_roles ON report_roles.report_id = reports.id";
$sql = mysqli_query($mysqli, $query);
if (!$sql) {
printf("Error: %s\n", mysqli_error($mysqli));
exit();
}
while($row = mysqli_fetch_array($sql, MYSQLI_ASSOC) ) {
if ($row['user_id'] == $id) {
echo "<input type='checkbox' name='" . ($row['id']) . "'" . "id='" . ($row['id']) . "'" . "value='yes'" . ($row['user_id'] == $id ? 'checked' : '') .">";
echo $row['report_name'];
} else {
echo "<input type='checkbox' name='" . ($row['id']) . "'" . "id='" . ($row['id']) . "'" . "value='yes'" . ">";
echo $row['report_name'];
}
}
If $id = 1 I am receiving this:
|checked| Report2 |checked| Report 1 |unchecked| Report2 |unchecked| Report 1 |unchecked| Report3
Which is completely right based on the code I wrote. I cannot figure out how to display all the reports without duplicates from reports table and check only those which are available in report_roles, something like this:
|checked| Report2 |checked| Report 1 |unchecked| Report3
I am sure I have to change my query with the join. Tried to do accomplish this task with two separate queries without joins but with no luck. Hope someone can help.
Actually I was just missing a statement in my query and thanks to Bernd Buffed I realized that I have to add one AND at the end of the query and it should look like this:
$query = "SELECT * FROM reports LEFT JOIN report_roles ON report_roles.report_id = reports.id AND user_id = $id";
Till now I was adding WHERE user_id = $id and was receiving only those reports which exists in report_roles. With the AND I am receiving all reports from reports table and my script can check only those which are in report_roles based on a simple php check.
Related
i don't know how to explain it so i will show you what i am trying to do.
mysql tables
Table Rules:
id| name|maker|model |type|price_rule
1 |client1|bmw |x5 | |24
2 |client2| | |2.0 |13
Table Products_client1:
id|maker|model |type|price
1 |bmw |x5 |2.4 |10
2 |opel |vectra|1.6 |5
3 |ford |mondeo|2.0 |15
now, i have a list of over 500k products in my mysql db, and need to update the price in the products table, with the rules from the rules table :
UPDATE products_client1,client2,... SET price=price+price_rule WHERE maker=maker or model=model or type=type
the thing is that not all clients in the Rule table have maker and model and type, some have only maker or only model or only type or a combination of the 3 and every client has a separate products table.
products_client1, products_client2.....
$sql = "SELECT * FROM Table_rule";
$Res = $conn->query ($sql) or die ("Error : " . $sql . "<br>" . $conn->error);
While($Row = $Res->fetch_assoc ()) { if (isset ($Row ["id"])) { $c_id[] = $Row ["id"]; if (isset ($Row ["name"])) { $c_name [] = $Row ["name"]; if (isset ($Row ["price_rule"])) { $c_price [] = $Row ["price_rule"]; }
$c_id_count = count($c_id);
For ($x=0; $x <> $c_id_count; $x++) { $sql_updt = "UPDATE Products_" . $c_name [$x] . " SET price=price+" . $c_price [$x] . " WHERE ";
$Conn->query ($sql_updt); }
Where what ? If this is = to this do this.....how to i check if every rule has 1...2....3....4...n maches or just 1 and hot do i apply price edit only to that item....there is always a match or more
my table fields are as below:
name | email | status | img_1 | img_2 | img_3 | img_4 | img_5 | img_6 | avail
so i want to add 6 images via a loop using php. but i cannot write the query to add images which are not static(i mean to say if some one add only 2 images or may be 1 images at the entry). pls help me. this is my basic query which i thought work.
$sql = "update product set img_".$dbfield." ='".$filename1."' where
id='".$iiid."'";
where $dbfield is the increment one by one to match the field name in img_1 img_2.
thank yoou in advance.
I m not sure what are achieving but I m assuming you want some think this.
$query = "UPDATE product SET";
$comma = " ";
$whitelist = array(
'img_1',
'img_2',
'img_3',
'img_4',
'img_5',
'img_6',
// ...etc
);
foreach($_POST as $key => $val) {
if( ! empty($val) && in_array($key, $whitelist)) {
$query .= $comma . $key . " = '" . mysql_real_escape_string(trim($val)) . "'";
$comma = ", ";
}
}
$sql = mysql_query($query);
Table 1 (Which needs to be updated)
+-----------------+
|name |qty |
+-----------------+
|area | 1 |
|length | 2 |
|breadth | 3 |
|width | 4 |
+-----------------+
Table Which needs to be fetched for what values and rows have to be update
+-------------------------------------+
|name | upd_qty | Cart_id | cid |
+-------------------------------------+
|area | 6 | 12 | 1 |
|length | 8 | 20 | 2 |
|breadth | 11 | 34 | 3 |
+-------------------------------------+
How can i do this using php. Help me with this please.
this is the code i have used for my original work. Table 1 & Table 2 have name in common and conditions are
1 . UPDATE should done for the rows which are fetched from table to with where condition.
2. Table 2 upd_qty will be updated in table 1 qty while fetching data from table 2 where condition.
$con=mysqli_connect("localhost","root","","medical");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
error_reporting(E_ALL ^ E_NOTICE);
$query = "SELECT * FROM cart WHERE cid='$id' AND 'cart'='$cart_id'";
$result = $con->query($query);
while($row = $result->fetch_assoc()) {
$mediname = $row['name'];
$mediqty = $row['upd_qty'];
for($i=0;$i<$count;$i++){
$sql="UPDATE stock SET qty='$mediqty' WHERE name='$mediname' AND
'cart'='$cart_id'";
if (!mysqli_query($con,$sql))
{
die('Error: Failed' . mysqli_error($con));
}
I don't think you need this line:
for($i=0;$i<$count;$i++){
There's already a "while fetch" loop.
Also, don't use single quotes around identifiers, use backticks if the identifier needs to be escaped.
With this:
... AND 'cart' = ...
'cart' will be evaluated a string literal, not a column reference.
With this
... AND `cart` = ...
cart is an identifier, a reference to a column.
Also, if we can't use prepared statements with bind placeholders, at a minimum, we use mysqli_real_escape_string to mitigate SQL Injection vulnerabilities
Also, there's a confusing mix of procedural style and objected oriented style calls...
procedural style
mysqli_query($con,$sql)
mysqli_error($con)
object oriented style
$con->query($query)
$result->fetch_assoc()
I recommend you choose one style or the other, and stick to that pattern.
$query = "SELECT * FROM cart WHERE `cid` = '"
. $con->real_escape_string($id)
. "' AND `cart` = '"
. $con->real_escape_string($cart_id)
. "'";
$result = $con->query($query);
if( !$result ) {
die('Error: ' . $con->error());
}
while( $row = $result->fetch_assoc() ) {
$mediname = $row['name'];
$mediqty = $row['upd_qty'];
$sql="UPDATE stock SET `qty` = '"
. $con->real_escape_string($mediqty)
. "' WHERE `name` = '"
. $con->real_escape_string($mediname)
. "' AND `cart` = '"
. $con->real_escape_string($cart_id)
."'";
if(!$con->query($sql) ) {
die('Error: Failed' . $con->error());
}
}
EDIT
If there's not a specific reason for the loop, if the goal is just to perform the UPDATE operation and there is not other logic or conditions, we can do the UPDATE in one statement, without a need for multiple query executions:
UPDATE cart c
JOIN stock s
ON s.cart = c.cart
AND s.name = c.name
SET s.qty = c.upd_qty
WHERE c.cid = ?
AND c.cart = ?
Personally, I would just do the one UPDATE statement using a prepared statement
// connect to mysql
$con = new mysqli(...)
if( $con->connect_error ) {
die( 'Connect error: ' . $con->connect_error );
}
// update statement
$sql = '
UPDATE cart c
JOIN stock s
ON s.cart = c.cart
AND s.name = c.name
SET s.qty = c.upd_qty
WHERE c.cid = ?
AND c.cart = ? ';
$sth = $con->prepare($sql);
if(!$sth) {
die( 'Prepare error: ' . $con->error() );
}
$sth->bind_param('ii',$id,$cart_id);
if(!$sth->execute()) {
die( 'Execute error: ' . $con->error() );
}
Code worked for me for what i want exactly is :
$con=mysqli_connect("localhost","root","","medical");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
error_reporting(E_ALL ^ E_NOTICE);
$query = "SELECT * FROM cart WHERE cid='$id' AND cart='$cart_id'";
$result = $con->query($query);
while($row1 = $result->fetch_assoc())
foreach ($result as $row1){
$sql="UPDATE stock SET qty='$row1[upd_qty]' WHERE name='$row1[name]'";
if (!mysqli_query($con,$sql))
{
die('Error: Failed' . mysqli_error($con));
}
}
i am new to PHP and mysql, I am trying to build a table. However, I have a very interesting bug that i can't fix.
code:
//Initializing mysql queries
//-----------------------SELECTING GOALS------------
$sql= "SELECT * FROM goals";
$records = mysql_query($sql);
//-----------------------SELECTING SERVICES---------
$sql2= "SELECT * FROM services";
$records2 = mysql_query($sql2);
//----------------SELECTING THE JUNCTION----------
$sql3 = "SELECT services.sid AS sid, services.name, objectives.oid
FROM services, objectives, servo
WHERE servo.s_id = services.id AND servo.obj_id = objectives.id";
$records3 = mysql_query($sql3);
$sql4 = "SELECT oid, gid, statement, GROUP_CONCAT(DISTINCT gid) AS GOID
FROM goals, objectives, obgoals
WHERE obgoals.go_id = goals.id AND obgoals.ob_id = objectives.id
GROUP BY oid";
$records4 = mysql_query($sql4);
<?php
while ($product = mysql_fetch_assoc($records2)) {
echo "<tr>";
$sid = $product['sid'];
$service = $product['name'];
echo "<td><a href='objectives.php?sid=" . $sid . "&service=" . $service . "'>" . $product['sid'] . "</a> </td>";
echo "<td>".$product['name']."</td>";
echo "<td>";
while ($g4services = mysql_fetch_assoc($records)) {
echo $g4services['gid'];
}
echo"</td>" ;
}
?>
Basically, my table has 30 rows and 3 columns, the last column is supposed to print out values from a database, this part is done by this piece of code
while ($g4services = mysql_fetch_assoc($records)) {
echo $g4services['gid'];
}
However, instead of printing the results for each row, it only prints the results for the first row, basically the first while loop runs and creates the the table with the 30 rows, but the second while loop only prints values on first row only. Essentially this is happening:
|SID|Name Of Service| Objectives|
-------------------------------
|S1| Service 1 | make the best cars|
|s2| Service 2 | |
|s3| Service 3 | |
|s4| Service 5 | |
|s5| Service 5 | |
.....
.....
....
|s30| Service30 | |
for some reason, my objectives column is not populated by the while loop, it only works for the first row. If someone can help me work the while loop to print the values for every row, it will be huge help. I will greatly appreciate it. Thanks.
The problem is that you're reading all the results of $records during the first iteration of the outer while loop. On future iterations, there are no more rows left, so the inner while loop completes immediately.
You can read those results once into a variable outside the loop, and then show that variable during the loop:
$all_g4services = '';
while ($g4services = mysql_fetch_assoc($records)) {
$all_g4services .= $g4services['gid'];
}
while ($product = mysql_fetch_assoc($records2)) {
echo "<tr>";
$sid = $product['sid'];
$service = $product['name'];
echo "<td><a href='objectives.php?sid=" . $sid . "&service=" . $service . "'>" . $product['sid'] . "</a> </td>";
echo "<td>".$product['name']."</td>";
echo "<td>$all_g4services;</td>" ;
}
Your second while loop is not required. It is runnning for each row. Remove it. Then for each row you have to find the entry that matches and echo only that.
echo $g4services['gid']
I dont know how to correct it for you as I dont know the relationship between the two.
I made this script which is giving me a lot of troubles. I'm not so good at MySQL and maybe I'm trying to do stuff too advanced for my knowledge of SQL, but I would really really really like to make this work.
My php script is:
<?PHP
$getusername=$_GET['user'];
$getpassword=$_GET['pass'];
$getworldname=$_GET['worldname'];
$getblock=$_GET['block'];
$getpos=$_GET['pos'];
$user_name = "asdasdasd";
$password = "asdasd";
$database = "asdasd";
$server = "localhost";
$db_handle = mysql_connect($server, $user_name, $password);
$db_found = mysql_select_db($database, $db_handle);
$SQL="SELECT * FROM accounts WHERE username='$getusername' and password='$getpassword'";
$result=mysql_query($SQL);
$count=mysql_num_rows($result);
if($count==1){
$blockstring=$getpos.'/'.$getblock.'|';
$SQL="SELECT LOCATE('$getpos', blocks) FROM worlds WHERE name='$getworldname'";
$result=mysql_query($SQL);
$count=mysql_num_rows($result);
echo $count;
//if there's already that block
if ($result!=0){
$posUnknown='|'.$getpos.'/';
$posKnown='|'.$getpos.'/'.$getblock;
$SQL="UPDATE worlds SET blocks=replace(blocks,concat('$posUnknown',substring_index(substring_index(blocks, '$posUnknown', 2), '|', 1),'|'),'$posKnown') WHERE name='$getworldname'";
$result=mysql_query($SQL);
}else{
$SQL="UPDATE worlds SET blocks=CONCAT(blocks,'$blockstring') WHERE name='$getworldname'";
$result=mysql_query($SQL);
}
print 'OK';
}else{
print 'NO';
}
?>
I'm sure I made some mistake, also big ones into the queries, but sadly I can't figure out what I'm doing wrong.
An example of the content of blocks could be:
x10y20z30/0|x999y1231z30/1|x3330y4444z0/99999|etc
What this script does, well, what I wanted it to do is:
Check username and password, and that works luckily,
check if the given block already exists in "blocks"
if it does exist replace the value (the one after the /) of the
already existing block with the new one,
if it doesn't exist just add it to "blocks".
But it doesn't work and I know why. I know it's because of the SQL, but I can't figure out how to make it work.
You have some serious issues with your code's security, as pointed out in a comment. I have done what I can without really changing what your code is doing:
<?PHP
$getusername=$_GET['user'];
$getpassword=$_GET['pass'];
$getworldname=$_GET['worldname'];
$getblock=$_GET['block'];
$getpos=$_GET['pos'];
$user_name = "asdasdasd";
$password = "asdasd";
$database = "asdasd";
$server = "localhost";
You should be using mysqli, not mysql:
$db = new mysqli($server, $user_name, $password, $database);
All input needs to be escaped before it is used in a query with real_escape_string:
$SQL="SELECT * FROM accounts WHERE username='" . $db->real_escape_string($getusername) . "' and password='" . $db->real_escape_string($getpassword) . "'";
$result=$db->query($SQL);
$count=$result->num_rows;
if($count==1) {
$blockstring=$getpos.'/'.$getblock.'|';
$SQL="SELECT LOCATE('" . $db->real_escape_string($getpos) . "', blocks) FROM worlds WHERE name='" . $db->real_escape_string($getworldname) . "'";
$result=$db->query($SQL);
$count=$result->num_rows;
echo $count;
//if there's already that block
if ($count!=0) {
$posUnknown='|'.$getpos.'/';
$posKnown='|'.$getpos.'/'.$getblock;
This is probably where you're having trouble, because it looks like you're storing all of this information in a single row:
$SQL="UPDATE worlds SET blocks=replace(blocks,concat('" . $db->real_escape_string($posUnknown) ."',substring_index(substring_index(blocks, '" . $db->real_escape_string($posUnknown). "', 2), '|', 1),'|'),'" . $db->real_escape_string($posKnown) . "') WHERE name='" . $db->real_escape_string($getworldname). "'";
$result=$db->query($SQL);
} else {
$SQL="UPDATE worlds SET blocks=CONCAT(blocks,'" . $db->real_escape_string($blockstring) ."') WHERE name='" . $db->real_escape_string($getworldname) . "'";
$result=$db->query($SQL);
}
print 'OK';
} else {
print 'NO';
}
?>
Since all of your block information is being shoved together in a single column, your database is not normalized at all and appears to be like this:
Worlds
name blocks
Your database should probably be structured a lot more like this:
Worlds
id | name
---------------
1 | demoworld
Blocks
id | WorldID | x | y | z | data
-----------------------------------------
1 | 1 | 10 | 20 | 30 | 0
2 | 1 | 999 | 1231 | 30 | 1
3 | 1 | 33330 | 4444 | 0 | 99999
You can recreate the data layout you provided when you query the data, and when someone tries to add something like x20y30z40/12345, you can parse that to get the x, y, z, and data portions.