I have this table
cityreportcomment :
-----------------
reportID (fK)
cityID (fK)
comment
EDIT: if city has no comment, there is no row in the table: a row (for a city) exists only if that city has a comment.
for every report, I print 13 cities (that are in another table). I would like to check if city has a comment, then echo comment, if not, echo 'different'; but my code doesn't work.
for ($i = 0; $i < 13; ++$i) {
$stmt = $conn->prepare("SELECT * FROM cityreportcomment WHERE reportID=? AND cityID=?");
if (!$stmt) {
die(printf("Error: %s.\n", mysqli_stmt_error($stmt)));
} else if (!$stmt->bind_param('ii', $reportID, $selectcityID_array_unique[$i])) {
die(printf("Error: %s.\n", mysqli_stmt_error($stmt)));
} else if (!$stmt->execute()) {
die(printf("Error execute from ereportcomment table: %s.\n", mysqli_stmt_error($stmt)));
} else {
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
if (isset($row['cityID']) && $row['cityID'] == $selectcityID_array_unique[$i]) {
$selectcomment2[] = 'same' . $row['cityID'] . (isset($row['comment']) ? $row['comment'] : "");
} elseif (!isset($row['cityID']) || $row['cityID'] != $selectcityID_array_unique[$i]) {
$selectcomment2[] = 'different';
}
}
}
/* end else */
$stmt->close();
echo $i . ' ' . $selectcomment2[$i] . '<br>';
} //end for
PROBLEM:
if $i=1 has comment, $i=2 no comment, $i=3 has comment, $i=4 no comment, my echo results is
1 comment1
2 comment3
3
4
5
.....
It should be
1 comment1
2 different
3 comment3
4 different
5 different
.....
Use this instead:
while ($row = $result->fetch_assoc()) {
if (!empty($row['cityID']) && $row['cityID'] == $selectcityID_array_unique[$i]) {
$selectcomment2[] = 'same' . $row['cityID'] . (!empty($row['comment']) ? $row['comment'] : "");
} elseif (empty($row['cityID']) || $row['cityID'] != $selectcityID_array_unique[$i]) {
$selectcomment2[] = 'different';
} else {
continue; # do nothing
}
}
Your if/else doesn't work because you are checking if $row['cityID'] "is set", in other words, if it exists or not... However, because you are using it on a mysql loop where you are returning those fields, they will always be set (exist). I suspect that what you want to check is, if $row['cityID'] is empty or not, which in that case you could use !empty() instead.
https://www.virendrachandak.com/techtalk/php-isset-vs-empty-vs-is_null/
You have this SQL:
"SELECT * FROM cityreportcomment WHERE reportID=? AND cityID=?"
You are binding $selectcityID_array_unique[$i] to the cityID placeholder, so every record returned will have a cityID equal to $selectcityID_array_unique[$i].
Then you are checking this:
if (isset($row['cityID']) && $row['cityID'] == $selectcityID_array_unique[$i]) {
Naturally, it will always be true. If no records are returned from the query, you will not see different, because the while loop will execute zero times.
You can fix it like this:
// remove the if from the while loop, as it really has no effect
while ($row = $result->fetch_assoc()) {
// you don't need the isset checks; if $row is set, then each value in it will be set
$selectcomment2[] = 'same' . $row['cityID'] . $row['comment']);
}
// if there's nothing in the comments after the loop, then put 'different' in it
if (!$selectcomment2) {
$selectcomment2[] = 'different';
}
If the comment is empty, it won't be !isset.
This code should do what you want:
I would like to check if city has a comment, then echo comment, if not, echo 'different'
$stmt = $conn->prepare("SELECT * FROM cityreportcomment WHERE reportID=? AND cityID=?");
$key = 0;
$stmt->bind_param('ii', $reportID, $key);
for ($i = 0; $i < 13; ++$i) {
$key = $selectcityID_array_unique[$i];
$stmt->execute();
$result = $stmt->get_result();
echo '<br>Results for cityID = ' . $key . '<br><br>';
while ($row = $result->fetch_assoc())
if (empty($row['comment']))
echo 'different<br>';
else
echo $row['comment'] . '<br>';
}
Related
I have this working where it will copy the row, and then link the new row to the previous row.
Where my issue is, is in copying over the NULL values. When I run this all null values go into the new row as blank.
How would I get it to change the value to NULL if it was originally NULL?
$result = $mysqli->query("SELECT * FROM rdpricing WHERE psid = '$dupsid';");
if($result->num_rows >= "1"){
$count = $result->num_rows;
$cols = array();
$result = $mysqli->query("SHOW COLUMNS FROM rdpricing");
while ($r = $result->fetch_array(MYSQLI_ASSOC)) {
if (!in_array($r["Field"], array("rdpid", "psid", "rdold"))) { //Excluding these columns
$cols[] = $r["Field"];
}
}
// Build and do the insert
$result = $mysqli->query("SELECT * FROM rdpricing WHERE psid = '$dupsid';");
while ($r = $result->fetch_array(MYSQLI_ASSOC)) {
$insertSQL = "INSERT INTO rdpricing (" . implode(", ",$cols) . ", rdold) VALUES (";
$count = count($cols);
foreach($cols as $counter=>$col) {
**// This is where I Believe it needs to happen, and what I have attempted, and it is NOT working**
if(empty($r[$col]) || is_null($r[$col]) || $r[$col] == ""){
$r[$col] = NULL;
}
$insertSQL .= "'" . $mysqli->real_escape_string($r[$col]) . "'";
if ($counter < ($count - 1)) {
$insertSQL .= ", ";
}
} // END foreach
$insertSQL .= ", '".$r["rdpid"]."');";
$mysqli->query($insertSQL);
if ($mysqli->affected_rows < 1) {
printf("%s\n", $mysqli->error);
} else {
}
$new_id = $mysqli->insert_id;
$statement = $mysqli->prepare("UPDATE rdpricing SET `psid`=? WHERE `rdpid`=?");
$statement->bind_param('ss', $new_psid, $new_id);
// Execute the prepared query.
$statement->execute();
$statement->close();
}
}
Generated from info in the comments:
#reset/create before the foreach, create an empty array
$insertSQLValues=array();
#in the foreach do some on given type
if(is_null($r[$col])){#real null
$r[$col] = "null";
} else if (empty($r[$col]) || $r[$col] == ""){#empty values
$r[$col] = "''";
} else {#standart data
$r[$col] = "'".$mysqli->real_escape_string($r[$col])."'";
}
$insertSQLValues[]=$r[$col];
#later
$insertSQL .= implode(', ',$insertSQLValues).", '".$r["rdpid"]."');";
Hopefully you can merge that into your code.
Below I have Php code that loops through an array and for each it checks if the value already exists in the database and if not, create it. The code itself is working but the loop itself can be insanely big, maximum of a couple tens thousand iterations.
How can I optimize this code? What to use and how to use. There should be a better way to insert this many times without looping through each individual.
foreach($arr as $value){
$checkID = mysqli_query($cenn, "SELECT item_id from items WHERE item_id = '$value'");
if (!$checkID) {
die("Query '$checkID' failed to execute for some reason");
}else{
if (mysqli_num_rows($checkID) > 0) {
$user = mysqli_fetch_array($checkID);
echo "item_id" . checkID . "exists already";
}
else{
echo "item_id: '$user_id' doesn't exist<br>";
$gw2Api = file_get_contents("https://api.guildwars2.com/v2/items/" . $user_id); //12452 30704
$gw2Api_result = json_decode($gw2Api,true);
/*Here would be some code to determine values that are being inserted*/
if (!array_key_exists("description",$gw2Api_result)) {
$description = 'No description available...';
} else{
if($gw2Api_result['description'] === ''){
$description = "No description available...";
} else {
$description = $gw2Api_result['description'];
}
}
$insertItem = "INSERT INTO items
(item_id, name, description,
AccountBindOnUse, AccountBound,
last_update
)
VALUES ('$user_id', '$gw2Api_result[name]', '$description',
'$AccountBindOnUse', '$AccountBound', CURRENT_TIMESTAMP)";
if ($cenn->query($insertItem) === true) {
echo "New record '$user_id' created successfully";
} else {
echo "Error: " . $sql . "<br>" . $cenn->error;
}
}
}
} // end foreach
The question: How to insert many values, new rows, into mysqli database as fast as possible.
Just use bulk insert.
Collect all the rows for insertion and pass it in one query.
echo 'hi';
if (!empty($arr)) {
echo 'ok';
$values = "'" . implode("', '", $arr) . "'";
$qExistingItemIds = mysqli_query($cenn, "SELECT item_id from items WHERE item_id IN($values)");
$existingItemIds = [];
while ($existingItemId = mysqli_fetch_array($qExistingItemIds)) {
$existingItemIds[] = $existingItemId['item_id'];
}
$arr = array_diff($arr, $existingItemIds);
$inserts = array();
$i = 0;
$ic = count($arr);
foreach ($arr as $value) {
$i++;
echo "item_id: $value doesn't exist<br>";
$gw2Api = file_get_contents("https://api.guildwars2.com/v2/items/" . $value); //12452 30704
$gw2Api_result = json_decode($gw2Api,true);
/*Here would be some code to determine values that are being inserted*/
if (!array_key_exists("description", $gw2Api_result)) {
$description = 'No description available...';
} else {
if ($gw2Api_result['description'] === '') {
$description = "No description available...";
} else {
$description = $gw2Api_result['description'];
}
}
$inserts[] = "
('$value', '$gw2Api_result[name]', '$description', '$AccountBindOnUse', '$AccountBound', CURRENT_TIMESTAMP)
";
if ($i == 50 OR $i == $ic) {
$inserts = implode(",", $inserts);
$insert = "
INSERT INTO items
(item_id, name, description, AccountBindOnUse, AccountBound, last_update)
VALUES
$inserts
";
if ($cenn->query($insert) === true) {
echo 'great';
echo "New records created successfully";
} else {
echo "Error: " . $sql . "<br>" . $cenn->error;
}
$ic -= 50;
$i = 0;
$inserts = array();
}
}
}
so now we have only 2 queries. not thousands
details about bulk insert:
http://www.geeksengine.com/database/data-manipulation/bulk-insert.php
If you use prepared statement you should reduce the round trips to the database server and only compile and optimise each query once instead of Number_of_inputs * 2 queries. This should reduce the workload.
I would be very interested to know by how much.
$sql = "SELECT item_id from items WHERE item_id = ?";
$db_select = $cenn->prepare($sql);
if ( ! $db_select ) {
echo $cenn->error;
exit;
}
$sql_insert = "INSERT INTO items
(item_id, name, description,
AccountBindOnUse, AccountBound, last_update)
VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)";
$db_insert = $cenn->prepare($sql);
if ( ! $db_insert ) {
echo $cenn->error;
exit;
}
foreach($arr as $value){
$db_select->bind_param('i', $value);
$res = $db_select->execute()
if ( $res === FALSE ) {
echo $cenn->error;
exit;
}
if ($db_select->num_rows > 0) {
// dont bother fetching data we already know all we need to
$user = $db_select->free();
echo "item_id $value exists already";
} else {
echo "item_id: $value doesn't exist<br>";
$gw2Api = file_get_contents("https://api.guildwars2.com/v2/items/" . $value);
$gw2Api_result = json_decode($gw2Api,true);
if ( ! array_key_exists("description",$gw2Api_result)
|| $gw2Api_result['description'] === '') {
$description = 'No description available...';
} else{
$description = $gw2Api_result['description'];
}
$db_insert->bind_param('issss', $value, $gw2Api_result[name],
$description, $AccountBindOnUse,
$AccountBound)
if ($cenn->query($insertItem) === true) {
echo "New record $value' created successfully";
} else {
echo "Error: " . $sql_insert . "<br>" . $cenn->error;
}
}
} // end foreach
I have this code
$dbh = new PDO('mysql:host=localhost;dbname=odesk', 'root', '123456');
$sth = $dbh->prepare("SELECT id,msisdn from new_r4 limit 1,10");
$sth2 = $dbh->prepare("SELECT status from flag where id = 1");
$sth->execute();
$sth2->execute();
while ($result = $sth->fetch(PDO::FETCH_ASSOC)) {
$result2 = $sth2->fetch(PDO::FETCH_ASSOC);
$flag = $result2['status'];
$the_number = $result['msisdn'];
$id = $result['id'];
while ($flag == 0) {
echo 'Waiting.......' . PHP_EOL;
sleep(1);
}
//Part of the condition,just added
while ($flag == 1) {
echo $the_number . ' ' . $id .' ' . PHP_EOL;
sleep(1);
}
}
which is a a cli script that displays some numbers from my address book if a certain condition is met.If a the flag is 0 then no number shall be displayed and when the flag is 1,then display the number.
The problem is,i can't find the right condition to use after
while ($flag == 0) {
echo 'Waiting.......' . PHP_EOL;
sleep(1);
}
The if , else and case do not wait up until the flag is 1.
What condition can i use to get the script to display the numbers when $flag == 1?.
You're using $result2 and $result1. Your $flag will always be the value id = 1 because the WHERE clause never changes - so either $flag will always be either 1 or another value (from your question, it's going to always be another value). Either change your query to join the table, or query whilst in the while loop.
Assuming new_r4.id = flag.id
SELECT r.`id`, r.`msisdn`, f.`status`
FROM new_r4 r
LEFT JOIN flag f
ON r.id = f.id
LIMIT 1, 10
Change your code to become
while ($result = $sth->fetch(PDO::FETCH_ASSOC)) {
$flag = $result['status'];
$the_number = $result['msisdn'];
$id = $result['id'];
Now all you need to do is check $flag is equal to 1, and you're golden.
if($flag == 1) {
echo $this_number . PHP_EOL;
}
The while ($flag == 0) { is infinite and will never break out ($flag never changes within the loop); so the rest of the code is never executed.
Why not just use a simple if/else statement ?
if($flag===1){
echo $the_number . ' ' . $id .' ' . PHP_EOL;
}else{
echo 'Waiting.......' . PHP_EOL;
}
I have a html form tat my user can use to search through a table in my MYSQL database.
By default if you just hit go it will display the entire table, however I would like them to be able select certain fields and my php form to search via the fields that are filled in.
I seem to be unable to find a way of doing this without writing a seperate query for all 11 inputs in the different combinations they could be entered in, which comes out at a total of 76 queries..
If anyone has a way to simplify this I would love any advice.
I have tried just running a query with the AND operator but that doesnt work as some variables can be left empty and that will return no result, not sure if that is what is upposed to happen, but that is what is happening.
my html and php:
http://jsbin.com/oquwid/1/edit
PHP
$sql = "SELECT * FROM ".$tbl_name."
WHERE fname='".$fname."'
and lname='".$lname."'
and city='".$city."'
and phone='".$pohne."'
and interest_inet='".$internet."'
and interest_tv='".$television."'
and interest_voice='".$voice."'
and submission_ip='".$ip."'
and inquiry_handled='".$handled."'";
$result = mysql_query($sql);
echo "<table border='1'>";
echo "<tr>";
$i = 0;
while ($i < mysql_num_fields($result))
{
$meta = mysql_fetch_field($result, $i);
echo "<th>".$meta->name."</th>";
$i++;
}
while ($row = mysql_fetch_row($result))
{
echo '<tr>';
foreach($row as $item)
{
echo "<td>".$item."</td>";
}
echo '</tr>';
echo $row;
}
echo "</table>";
You could append parts to the query depending on which are filled in:
if(!empty($fname) || !empty($lname) || !empty($city) || etc.etc.) {
$sql = "SELECT * FROM $tbl_name WHERE ";
$queryParts = array();
if($fname != "") {
$queryParts[] = " fname='$fname'";
}
if($lname != "") {
$queryParts[] = " lname='$lname'";
}
etc.etc.
$sql .= implode(" AND ", $queryParts);
// do query, etc.
}
else {
// Don't do query if no parameters are specified
}
You also need to make sure that you escape all of your query parameters before you use them or risk having someone ravage your data.
The following uses loops to avoid duplicate code:
$fieldIsSpecified = false;
$queryFields = array('fname' => $fname, 'lname' => $lname, 'city' => $city, etc...);
foreach($queryFields as $column => $value) {
if(!empty($value){
$fieldIsSpecified = true;
break;
}
}
if($fieldIsSpecified) {
$sql = "SELECT * FROM $tbl_name WHERE ";
$queryParts = array();
foreach($queryFields as $column => $value) {
if(!empty($value)) {
$queryParts[] = " $column = '$value'";
}
}
$sql .= implode(" AND ", $queryParts);
// do query, etc.
}
else {
// Don't do query if no parameters are specified
}
The reason you're query isn't working if a value is not filled in, is probably because the query results in this (given first name is empty)
SELECT * FROM $tbl_name WHERE fname=''
And there probably isn't a user having no first name.
Further, you considered adding a flag per requested info, and on base of that either add or remove the needed part to the select part of the query ?
For example,
$sql = "SELECT * FROM $tbl_name WHERE ";
$queryChanged = false;
if (isset($fname)){
if (!empty($fname)){
$sql .= "fname='$fname' ";
$queryChanged=true;
}
}
if (isset($lname)){
if (!empty($lname)){
$sql .= ($queryChanged) ? " AND lname='$lname'" : "lname='$lname'";
$queryChanged = true;
}
}
... //Continue the logic
I'd recommend you to read this post about select * as well as this about user input and how to handle it
this is how i am going to have to do it
php:`
//if just lname is set
if(empty($start_date) && empty($end_date) && empty($fname) && isset($lname) && empty($city) &&
empty($internet) && empty($television) && empty($voice) && empty($phone) && empty($ip) &&
empty($handled) && empty($not_handled)){
$sql = "SELECT * FROM ".$tbl_name."
WHERE lname='".$lname."'";
$result = mysql_query($sql);
echo "<table border='1'>";
echo "<tr>";
$i = 0;
while ($i < mysql_num_fields($result))
{
$meta = mysql_fetch_field($result, $i);
echo "<th>".$meta->name."</th>";
$i++;
}
while ($row = mysql_fetch_row($result))
{
echo '<tr>';
foreach($row as $item)
{
echo "<td>".$item."</td>";
}
echo '</tr>';
}
echo "</table>";
exit();
}
//if just city is selected
if(empty($start_date) && empty($end_date) && empty($fname) && empty($lname) && isset($city) &&
empty($internet) && empty($television) && empty($voice) && empty($phone) && empty($ip) &&
empty($handled) && empty($not_handled)){
$sql = "SELECT * FROM ".$tbl_name."
WHERE city='".$city."'";
$result = mysql_query($sql);
echo "<table border='1'>";
echo "<tr>";
$i = 0;
while ($i < mysql_num_fields($result))
{
$meta = mysql_fetch_field($result, $i);
echo "<th>".$meta->name."</th>";
$i++;
}
while ($row = mysql_fetch_row($result))
{
echo '<tr>';
foreach($row as $item)
{
echo "<td>".$item."</td>";
}
echo '</tr>';
}
echo "</table>";
exit();
}
And etc... i am going to have to repeat this process until i cover all, 76 i believe, possibilites. thnkfully its just a lot of copy paste. thanks for the help everyone
First don't use MYSQL_*. Use PDO
Second, with your code, your are requiring all fields to be filled.
If you don't wanna do that then go this way:
You can use WHERE 1=1 , but it's not recommended !!!!!
$sql = "SELECT * FROM ".$tbl_name." WHERE confirm = '0' ";
$sql .= "AND fname = ".$fname."";
$sql .= "AND lname = ".$lname."";
$sql .= "AND city = ".$city."";
$sql .= "AND phone = ".$pohne."";
$sql .= "ORDER BY date DESC";
$result = mysql_query($sql);
echo "<table border='1'>";
echo "<tr>";
$i = 0;
while ($i < mysql_num_fields($result))
{
$meta = mysql_fetch_field($result, $i);
echo "<th>".$meta->name."</th>";
$i++;
}
while ($row = mysql_fetch_row($result))
{
echo '<tr>';
foreach($row as $item)
{
echo "<td>".$item."</td>";
}
echo '</tr>';
echo $row;
}
echo "</table>";
I am making a login page that checks for matching values in a database if the SELECT query returns a matching row with username and password then it will return a row count of 1. The way I have it coded right now when I echo the variable that stores the row count it will echo 26 for some reason and I'm not to sure why.
Would someone explain if I am doing something wrong or if this is normal behavior and where that value is coming from?
function checkLogin($conn,$myusername,$mypassword,$row,$row1){
try {
$sql = "SELECT COUNT(*) FROM CLL_users WHERE user_name = 'user' AND password = 'XXXX'";
if ($results = $conn->query($sql)) {
if($results->fetchColumn() > 0) {
$sql = "SELECT * FROM CLL_users WHERE user_name = 'user' AND password = 'XXXXX'";
foreach ($conn->query($sql) as $row)
{
$rowCount = count($row);
echo $rowCount;
print ("Username: " . $row['user_name'] . "<br>");
print ("Username: " . $row['password'] . "<br>");
}
echo $count;
}
else {
print "NO ROWS";
}
}
} catch (PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}
}
Your code, $rowCount = count($row);, is counting the columns in the current row - not the number of rows returned by the query.
On the same note, you are echoing a second count related variable, $count, but you neither declare-it nor increment it in your code. It looks like this one is the one that's supposed to be counting the number of rows you loop through. If this is true, you should set it as $count = 0; before the loop and use $count++; within it:
$count = 0;
foreach ($conn->query($sql) as $row) {
print ("Username: " . $row['user_name'] . "<br>");
print ("Username: " . $row['password'] . "<br>");
$count++;
}
echo $count;
Also, you're currently using PDO's rowCount prior to selecting a user, and you're using it properly. You could just store that result into a variable and use it to tell how many rows you are receiving:
$sql = "SELECT COUNT(*) FROM CLL_users WHERE user_name = 'user' AND password = 'XXXX'";
if ($results = $conn->query($sql)) {
$numRows = $results->fetchColumn();
if($numRows > 0) {
... rest of your code ....
function checkLogin($conn,$myusername,$mypassword,$row,$row1)
{
try
{
$sql = "SELECT COUNT(*) FROM CLL_users WHERE user_name = 'user' AND password = 'XXXX'";
if ($results = $conn->query($sql))
{
$count = $results->fetchColumn();
echo "$count\n";
if($count > 0)
{
$sql = "SELECT * FROM CLL_users WHERE user_name = 'user' AND password = 'XXXXX'";
foreach ($conn->query($sql) as $row)
{
print ("Username: " . $row['user_name'] . "<br>");
print ("Username: " . $row['password'] . "<br>");
}
}
else
{
print "NO ROWS";
}
}
}
catch (PDOException $e)
{
echo 'Connection failed: ' . $e->getMessage();
}
}