php for each loop not functioning - php

I am attempting to clean up a database table that might be missing book titles or bio information. The user is supposed to be able to click a button and the program does the rest.
I have run the query in my database and it returns the information I am looking for, so i think my issue is with the for each loop.
Here is my code:
<?php
require_once ('../db.php');
require_once ('../amazon/amazon.php');
$conn = db_connect();
session_start();
$x = 0;
// find all of the books with no Titles or Bios
$result = $conn->query("
select
i.date_created,
users.username,
i.sku,
i.isbn13,
i.quantity,
source.source,
i.date_process,
location.location
from inventory i
left join book on i.isbn13 = book.isbn13
left join source on i.source_id = source.source_id
left join location on i.location_id = location.location_id
left join users on i.created_by = users.user_id
where sku > '10000000'
and quantity >= 1
and (book.title = ''
or book.title is null
or book.author = ''
or book.author is null)
and i.isbn13 >1");
$num_rows = $result->num_rows;
if($num_rows > 0)
{
while($row = $result->fetch_assoc()) {
$isbnArray[$x] = $row['isbn13'];
$qtyArray[$x] = $row['quantity'];
$x++;
} // end of while loop
$sum = array_sum($qtyArray);
for each ($isbnArray as $isbn)
{
//retrieve amazon data
$parsed_xml = amazon_xml($isbn);
$amazonResult = array();
$current = $parsed_xml->Items->Item;
if($parsed_xml->Items->Request->IsValid == 'True') {
$amazonResult = array(
'Title' => $current->ItemAttributes->Title,
'Author' => $current->ItemAttributes->Author,
'Edition' => $current->ItemAttributes->Edition,
'Weight' => ($current->ItemAttributes->PackageDimensions->Weight / 100),
'Publisher' => $current->ItemAttributes->Publisher,
'PublishDate' => $current->ItemAttributes->PublicationDate,
'Binding' => $current->ItemAttributes->Binding,
'SalesRank' => $current->SalesRank,
'ListPrice' => str_replace('$','',$current->ItemAttributes->ListPrice->FormattedPrice),
'ImageURL' => $current->LargeImage->URL,
'DetailURL' => $current->DetailPageURL
);
} // end of if statement
//update Title and Bio info in book table
$conn->query("
update book
set isbn13 = '$isbn',
author = '" . $amazonResult['Author'] . "',
title ='" . $amazonResult['Title'] . "',
edition = '" . $amazonResult['Edition'] . "',
weight = '" . $amazonResult['Weight'] . "',
publisher = '" . $amazonResult['Publisher'] . "',
binding = '" . $amazonResult['Binding'] . "',
listed_price = '" . $amazonResult['ListPrice'] . "',
pub_date = '" . $amazonResult['PublishDate'] . "'
WHERE isbn13 = '$isbn'");
} // end of for each loop
}
$message = array( 'message' => $sum.' Records were updated' );
$conn->close();
echo json_encode($message);
?>
To me everything looks right, but when I run it with firebug on, there is no message. Console.log(data) in my success function says empty string.
What am I doing wrong? Should I restructure my for each loop?
EDIT: I changed parts of the code to get an accurate count of how many records were updated. This is the $qtyArray[$x] = $row['quantity'] line. My console.log(data) shows that 2995 records were updated, but the #message does not appear on the screen, just the console.log(data). Hope this gives a little more insight.

Your error may lie in your while loop:
while($row = $result->fetch_assoc()) {
$isbnArray[$x] = $row['isbn13'];
$sum = array_sum($isbnArray);
} // end of while loop
$x is initialized to 0, and never changed, so you just overwrite the same entry in the array each time.
You have to change:
$isbnArray[$x] = $row['isbn13'];
to:
$isbnArray[] = $row['isbn13'];

You need to escape your " in your query
$result = $conn->query("
select
i.date_created,
users.username,
i.sku,
i.isbn13,
i.quantity,
source.source,
i.date_process,
location.location
from inventory i
left join book on i.isbn13 = book.isbn13
left join source on i.source_id = source.source_id
left join location on i.location_id = location.location_id
left join users on i.created_by = users.user_id
where sku > '10000000'
and quantity >= 1
and (book.title = \"\"
or book.title is null
or book.author = \"\"
or book.author is null)
and i.isbn13 >1");

Related

Joining two tables based off a condition SQL

I am building an android app that uses geo location. I am trying to improve my overall app to improve its smoothness while running. I am using volly to connect to a php page on my web sever where the php page can then access my phpmyadmin database. My php page for updating locations is a horrible mess and I was hoping it can be fixed with the right sql query.
Lets get down to it.
So I have a table named users
and a table named friends
In this particular example david is friends with mark and jack. Also to clarify mark and jack are friends with david.
What I need to do is Write a query if given a user ID say for example 3 that will produce a table of that person and his friends ID, cordsV1, cordsV2 without any duplicate IDs in the table.
I was able to get this to work with using loops and variables ect but as I said it is a horrible mess.
Here is my current all sql query attempt:
SELECT DISTINCT ID, cordsV1, cordsV2 FROM `friends`,`users` WHERE user_one_ID = 1 AND status = 1;
HOWEVER this just returns all of the user IDs from the user table. I am really bad with sql so if someone could point me in the right direction it would be much appreciated.
Here is my horrible mess of code if you were wondering:
<?php error_reporting(E_ALL | E_STRICT); ?>
<?php
$THIS_USER_ID = $_GET['THIS_USER_ID'];
try {
$one = 1;
$db = new PDO("");
$sql = "SELECT * FROM friends WHERE user_one_ID = '" . $THIS_USER_ID . "' AND status = '" . $one . "' OR user_two_ID = '" . $THIS_USER_ID . "' AND status = '" . $one . "'";
$rows = $db->query($sql)
->fetchAll(PDO::FETCH_ASSOC);
$printMe = [];
foreach($rows as $row){
$printMe[] = $row;
}
$jsonArr = json_encode($printMe);
$characters = json_decode($jsonArr, true);
// Getting the size of the sample array
$size = sizeof($characters);
$neg = -1;
$sql2 = "SELECT * FROM users WHERE ID = '" . $neg . "'";
$sql3 = "";
$sql4 = "";
for ($x = 0; $x < $size; $x++ ){
if ($characters[$x]['user_one_ID'] == $THIS_USER_ID && $characters[$x]['status'] == 1){
$hold = $characters[$x]['user_two_ID'];
$sql3 = $sql3 . " OR ID = '" . $hold . "'";
} else if($characters[$x]['user_two_ID'] == $THIS_USER_ID && $characters[$x]['status'] == 1) {
$hold = $characters[$x]['user_one_ID'];
$sql4 = $sql4 . " OR ID = '" . $hold . "'";
}
}
$sql5 = $sql2 . $sql3 . $sql4;
$sql7 = "SELECT * FROM users WHERE ID = '" . $THIS_USER_ID . "'";
$printMe2 = [];
$rows3 = $db->query($sql7)
->fetchAll(PDO::FETCH_ASSOC);
foreach($rows3 as $row3){
$printMe2[] = $row3;
}
$rows2 = $db->query($sql5)
->fetchAll(PDO::FETCH_ASSOC);
foreach($rows2 as $row2){
$printMe2[] = $row2;
}
$jsonArr2 = json_encode($printMe2);
echo $jsonArr2;
$db = null;
} catch(PDOException $ex) {
die(json_encode(array('outcome' => false, 'message' => 'Unable to connect')));
}
?>
Get the user-data
SELECT
*
FROM
users
WHERE ID = ?
Get the user-data of friends
SELECT
users.*
FROM
friends
JOIN
users ON users.ID = friends.user_two_ID
WHERE
friends.user_one_ID = ?
Better use prepared statements, or your app wont be alive very long due to SQL-Injections.
You also want to have a look at meaningful names.

PHP query on loop slowly [duplicate]

I have this php function to check and insert data from text file to database.
//Get All Model
$qModel = oci_parse($c1, "SELECT MODELID, MODEL_NAME FROM MEP_TBL_MODEL WHERE ACTIVE = 'Y' AND LOCATION = 'PCBA' ORDER BY MODELID ASC");
oci_execute($qModel);
while($dModel = oci_fetch_array($qModel))
{
//Configuration
$qDtl = oci_parse($c1, "SELECT * FROM MEP_TBL_MODEL_CONFIGURATION WHERE MODELID_FK = '" . $dModel['MODELID'] . "'");
oci_execute($qDtl);
while($dDtl = oci_fetch_array($qDtl))
{
$modelIDAccept[] = $dDtl['CONFIGURATIONID'];
$dateCode = date($dDtl['DATE_CODE']);
$readRowAfter = date($dDtl['READ_ROW_AFTER']);
$createFromFormat = $dDtl['CREATE_FROM_FORMAT'];
$ipAddress = $dDtl['IP_ADDRESS'];
$status = $dDtl['STATUS'];
if($dDtl['SOURCE'] != "")
{
$source = "\\".$dDtl['SOURCE'];
}
else
{
$source = "";
}
if(empty($ipAddress))
{
$fileAccept = file_get_contents("\\\\192.168.184.13\\Reports\\".$dModel['MODEL_NAME'].$source."\\Accept\\Accept_".$dDtl['MODEL_CODE']."_".$dateCode."_".$dDtl['TS_CODE'].".txt");
$linesAccept = explode("\n",$fileAccept);
$rowsintimespanAccept = 0;
for($i = $readRowAfter; $i < count($linesAccept); $i++)
{
$dateobjAccept = DateTime::createFromFormat($createFromFormat, $linesAccept[$i]);
if($dateobjAccept < $toDateTime && $dateobjAccept > $fromDateTime)
{
$rowsintimespanAccept++;
$logDate = $dateobjAccept->format('Y-m-d H:i:s');
//I put select query and insert here but it so slow.
$qChk = oci_parse($c1, "SELECT * FROM MEP_TBL_OUTPUT_DETAILS WHERE MODELID_FK = '" . $dModel['MODELID'] . "' AND RUNNING_DATE = TO_DATE('$logDate', 'YYYY-MM-DD hh24:mi:ss') AND TS_CODE = '" . $dDtl['TS_CODE'] . "' AND SHIFT = 'Morning' AND QUANTITY_STATUS = 'OK' AND CONFIGURATIONID_FK = '" . $dDtl['CONFIGURATIONID'] . "'");
oci_execute($qChk);
if(oci_fetch($qChk) > 0)
{
}
else
{
$qInsert = oci_parse($c1, "INSERT INTO MEP_TBL_OUTPUT_DETAILS(MODELID_FK, RUNNING_DATE, QUANTITY_STATUS, TS_CODE, SHIFT, CONFIGURATIONID_FK) VALUES('" . $dModel['MODELID'] . "', TO_DATE('$logDate', 'YYYY-MM-DD hh24:mi:ss'), 'OK', '" . $dDtl['TS_CODE'] . "', 'Morning', '" . $dDtl['CONFIGURATIONID'] . "')");
oci_execute($qInsert);
}
}
}
$totalAccept[] = $rowsintimespanAccept;
}
}
}
When I tried to run the code, I got very slow loading the page and sometimes it show me time out execution.
My question, is there any way to make the query fast maybe inside or outside the loop? I knew it slow because when I remove the select and insert query, the load page is only 3-4 seconds.
If I've read your code correctly, what you're after is a single MERGE statement that you can run on the database. I don't know PHP, so I can't give you how it should be called, but I can give you the SQL statement to run:
MERGE INTO mep_tbl_output_details tgt
USING (SELECT mtm.modelid,
mtm.model_name,
mtmc.configurationid,
mtmc.date_code,
mtmc.read_row_after,
mtmc.create_from_format,
mtmc.ip_address,
mtmc.status,
mtmc.ts_code
FROM mep_tbl_model mtm
INNER JOIN mep_tbl_model_configuration mtmc ON mtm.modelid = mtmc.modelid_fk
WHERE mtm.active = 'Y'
AND mtm.location = 'PCBA') src
ON (tgt.modelid_fk = src.modelid
AND tgt.ts_code = src.ts_code
AND tgt.configurationid_fk = src.configurationid
AND tgt.runningdate = :log_date
AND tgt.shift = 'Morning'
AND tgt.quantity_status = 'OK')
WHEN NOT MATCHED THEN
INSERT (tgt.modelid_fk, tgt.running_date, tgt.quantity_status, tgt.ts_code, tgt.shift, tgt.configuration_fk)
VALUES (src.modelid, :log_date, 'OK', src.ts_code, 'Morning', src.configurationid);
This does the join you were reinventing with your loops, links it back to the table you're trying to insert into, and only inserts a row if it doesn't already exist in the table.
You would need to write the PHP code to execute this, having passed the log_date in as a bind variable.
By binding the variable, you allow the database to skip the hard parse (i.e. finding out the best way to execute the query), which saves time.
By not fetching data and manually looping round before selecting more data and working out if you need to do the insert, you skip a whole lot of context switching and pulling/pushing data across the network. Let the database do the heavy lifting; it's what it's designed to do!

How to show data category wise using MySQl

This is mySQL Fiddle I am trying to show data in DataTables using this query but if I want to show data accordingly with each brand wise and category wise. What should I change in this query?
$q = intval($_POST['Name']);
$time = strtotime($_POST['Date']);
$day = date('d',$time);
$month = date('m',$time);
$year = date('Y',$time);
$query = "
SELECT d.distributor_name
, s.order_date
, p.product_name
, s.nsp
, s.current_sales
, s.closing_balance
FROM sales s
LEFT
JOIN product p
ON p.product_id = s.product_id
LEFT
JOIN distributor d
ON s.d_id = d.d_ID
WHERE MONTH(s.order_date) = '" . $month . "'
AND YEAR(s.order_date) = '" . $year . "'
AND d.d_id = '" . $q . "';
";
$result = $connect->query($query);
$array = array();
while ($row = mysqli_fetch_assoc($result)) {
$array['data'][] = $row;
}
echo json_encode($array);
$connect->close();

PHP MySQL $_POST

I am trying to create a PHP form using MySQL database.
I have created a dropdown list with the names of samples (like Al, Au...) and a textbox for the values.
My problem that the units are in my database sometimes in ppm, sometimes in pph.
How can I set if the values are in pph, use the $value=$_POST["value"]/10000;
if the values are in ppm, use $value=$_POST["value"]?
Any idea?
My code:
<?php
if (isset($_POST["sample"]))
{
$sample = $_POST["sample"];
$unit = mysql_query("SELECT unit FROM analysis where sample='" . $sample . "'");
if ($unit == 'pph')
{
$value = $_POST["value"] / 10000;
$sql = "SELECT
a.sample,
concat (a.modif, (IF (unit='pph',10000*value,value))),
a.method,
a.mkey,
b.name,
b.from,
b.to,
b.type
FROM
anlysis a,
sample b
WHERE
a.mkey=b.mkey AND sample = '$sample' AND value > '$value'";
$result = mysql_query($sql);
}
else
{
$value = $_POST["value"];
$sql = "SELECT
a.sample,
concat ( a.modif, ( IF (unit = 'pph', 10000 * value, value) ) ),
a.method,
a.mkey,
b.name,
b.from,
b.to,
b.type
FROM
anlysis a,
sample b
WHERE
a.mkey = b.mkey AND sample = '$sample' AND value > '$value'";
$result = mysql_query($sql);
}
}
Thank you!
Here's what I'd suggest:
<?php
if (isset($_POST["sample"])) {
$sample = htmlspecialchars(trim($_POST["sample"])); //A little clean-up wont hurt...
$unit = mysql_query("SELECT unit FROM analysis where sample='" . $sample . "'");
if ($unit == 'pph'){
$postVal= htmlspecialchars(trim($_POST["value"]));
$value = $postVal / 10000;
$sql = "SELECT a.sample,
concat (a.modif, (IF (unit='pph',10000*value, value))),
a.method,
a.mkey,
b.name,
b.from,
b.to,
b.type
FROM
analysis AS a
LEFT JOIN sample AS b
ON a.mkey=b.mkey
WHERE
a.sample='" . $sample . "' AND a.value > '" . $value ."'";
$result = mysql_query($sql);
}
else
{
$postVal= htmlspecialchars(trim($_POST["value"]));
$value = $postVal;
$sql = "SELECT
a.sample,
concat ( a.modif, ( IF (unit = 'pph', 10000 * value, value) ) ),
a.method,
a.mkey,
b.name,
b.from,
b.to,
b.type
FROM
analysis AS a
LEFT JOIN sample AS b
ON a.mkey=b.mkey
WHERE
a.mkey = b.mkey AND sample = '" . $sample . "' AND value > '" . $value . "'";
$result = mysql_query($sql);
}
first
$analysis = mysql_fetch_object($query);
then you can access the value
if ($analysis->unit == 'pph')

Using SQL and PHP to return ranked results from MySQL

I'm trying to come up with the correct syntax for a SQL query using PHP (in a drupal site) but I need some guidance.
Here is my idea (in Drupal module - already designed). User makes selections from multi-page form (3 pages, radio buttons on each page, only 1 selection allowed per page). I want these to be submitted to the database and have the MySQL database return recommendations for the user depending on what their selections were, ranked in order of how many of their selections match those criteria in the resources in the database. So for example a user might select novice for exp level and founder for role and entrepreneuralship (made up word) as their topics of interest (the 3 questions in the form).
If a Resource in the database had all 3 of these set for those fields (as part of a field list), we'd want it returned near the top of the results (if more than 1 had all 3 we'd want them ordered alphabetically - ascending), followed by any resources that had at least 2 of these matching list terms (with corresponding alphabetic ranking between those second tier resources), followed by items that matched only ONE of the checked items. Items that return 0 matches shouldn't be displayed at all.
What I've done is put together a Drupal and PHP code-based concept I'm hoping for feedback on this. The code below is the function that's called after the user submits the form and are redirected to the /recommendations page. What I'd like feedback on primarily is setting the PHP variables at the top, the SQL in my $result var which is my best guess how this would work, and then a bunch of if/while statements to do the ordering and returning of data to the screen.
Any help in making this more functional code would be greatly appreciated. Thank you!
function pathfindertool_recommendations_page() {
$output = '';
$level = $_SESSION['level'];
$level = mysql_real_escape_string($level);
$role = $_SESSION['role'];
$role = $level = mysql_real_escape_string($role);
$topic = $_SESSION['topic'];
$topic = mysql_real_escape_string($topic);
$result = db_query("SELECT n.nid, n.title, n.type, fdb.body_value, fdfe.field_experience_level_value, fdfi.field_icon, fdfl.field_link_url, fdfr.field_role_value, fdft.field_topics_value FROM {node} as n INNER JOIN {field_data_body} as fdb INNER JOIN {field_data_field_experience} as fdfe INNER JOIN {field_data_field_icon} as fdfi INNER JOIN {field_data_field_link} as fdfl INNER JOIN {field_data_field_role} as fdfr INNER JOIN {field_data_field_topics} as fdft on n.nid = fdb.entity_id on n.nid = fdfe on n.nid = fdfi on n.nid= fdfl on n.nid = fdfr on n.nid = fdft WHERE n.type = :type", array(':type' => 'resource',) "AND fdfe.field_experience_level_value = :level", array(':level' => '$level',) "AND fdfr.field_role_value = :role", array(':role' => '$role',) AND fdft.field_topics_value = :topic", array(':topic' => '$topic',) ORDER BY ASC);
if($result) {
while ($row = $result->fetchAssoc()) {
// If all three match
while (($row['field_data_experience_level'] = $level) && ($row['field_data_field_role'] = '$role') && ($row['field_data_field_topics'] = $topic)) {
$title = row['title'];
$link = row['field_data_field_link'];
$body = row['body_value'];
$icon = row['field_icon'];
$output .= '<p> . $title . <br> . $icon . <br> . $body . <br> . $link';
return $output;
}
// If at least two match
while (($row['field_data_experience_level'] = $level) && ($row['field_data_field_role'] = '$role') OR ($row['field_data_field_topics'] = $topic)) {
$title = row['title'];
$link = row['field_data_field_link'];
$body = row['body_value'];
$icon = row['field_icon'];
$output .= '<p> . $title . <br> . $icon . <br> . $body . <br> . $link';
return $output;
}
while (($row['field_data_experience_level'] = $level) OR ($row['field_data_field_role'] = '$role') && ($row['field_data_field_topics'] = $topic)) {
$title = row['title'];
$link = row['field_data_field_link'];
$body = row['body_value'];
$icon = row['field_icon'];
$output .= '<p> . $title . <br> . $icon . <br> . $body . <br> . $link';
return $output;
}
// Just if only one matches
while (($row['field_data_experience_level'] = $level) OR ($row['field_data_field_role'] = '$role') OR ($row['field_data_field_topics'] = $topic)) {
$title = row['title'];
$link = row['field_data_field_link'];
$body = row['body_value'];
$icon = row['field_icon'];
$output .= '<p> . $title . <br> . $icon . <br> . $body . <br> . $link';
return $output;
}
}
}
Here's my SQL:
$result = db_query("
SELECT n.nid,
n.title,
n.type,
fdb.body_value,
fdfe.field_experience_level_value,
fdfi.field_icon,
fdfl.field_link_url,
fdfr.field_role_value,
fdft.field_topics_value
FROM {node} AS n
INNER JOIN {field_data_body} AS fdb
INNER JOIN {field_data_field_experience} AS fdfe
INNER JOIN {field_data_field_icon} AS fdfi
INNER JOIN {field_data_field_link} AS fdfl
INNER JOIN {field_data_field_role} AS fdfr
INNER JOIN {field_data_field_topics} AS fdft ON n.nid = fdb.entity_id ON n.nid = fdfe ON n.nid = fdfi ON n.nid= fdfl ON n.nid = fdfr ON n.nid = fdft
WHERE n.type = :type
",
array(':type' => 'resource',) "AND fdfe.field_experience_level_value = :level", array(':level' => '$level',) "AND fdfr.field_role_value = :role", array(':role' => '$role',) AND fdft.field_topics_value = :topic", array(':topic' => '$topic',) ORDER BY ASC);

Categories