I'm having an issue preparing a SQL statement:
$statement = $conexion->prepare(
'SELECT * FROM celulares
WHERE (MARCA = :marca )
AND
(CATEGORIA = :categoria1 OR CATEGORIA = :categoria2 OR CATEGORIA = :categoria3)
AND
(CATEGORIA2 = :categoria1 OR CATEGORIA2 = :categoria2 OR CATEGORIA2= :categoria3)
AND
(CATEGORIA3 = :categoria1 OR CATEGORIA3 = :categoria2 OR CATEGORIA3 = :categoria3)');
Giving placeholders values with this:
$statement->execute(array(':categoria1' => $categoria1,
':categoria2' => $categoria2,
':categoria3' => $categoria3,
':marca' => $query
));
$query value may variate when my application begins depending on some results:
if ($entrada == "LG") {
if ($query == "") {
$query = "LG";
} else {
$query = $query . ' OR MARCA = "LG" ';
}
}
if ($entrada == "APPLE") {
if ($query == "") {
$query = "APPLE";
} else {
$query = $query . ' OR MARCA = "APPLE" ';
}
}
if ($entrada == "HUAWEI") {
if ($query == "") {
$query = "HUAWEI";
} else {
$query = $query . ' OR MARCA = "HUAWEI" ';
}
}
I tried a lot of things, but none of those worked out it returns an empty array, the only one who works was changing this line of my prepared statement:
WHERE (MARCA = :marca OR MARCA = :marca2 OR MARCA = :marca3 )
And as many "MARCA" as results, i think it's not the best way to do it
UPDATED:
Now trying with IN Statement in my Query (Thanks you all for helping me)
Now it looks like:
$marcas = array("LG", "HUAWEI"); (Static values for test)
$inQuery = implode(',', array_fill(0, count($marcas), '?'));
$statement = $conexion->prepare(
'SELECT * FROM celulares
WHERE (MARCA = IN (' . $inQuery . '))
AND
(CATEGORIA = :categoria1 OR CATEGORIA = :categoria2 OR CATEGORIA = :categoria3)
AND
(CATEGORIA2 = :categoria1 OR CATEGORIA2 = :categoria2 OR CATEGORIA2= :categoria3)
AND
(CATEGORIA3 = :categoria1 OR CATEGORIA3 = :categoria2 OR CATEGORIA3 = :categoria3)');
foreach ($marcas as $k => $marca) {
$statement->bindValue(($k+1), $marca);
}
$statement->bindValue(':categoria1', $categoria1);
$statement->bindValue(':categoria2', $categoria2);
$statement->bindValue(':categoria3', $categoria3);
$statement->execute();
Getting: Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters
Trying to fix it
You can simplify your query:
SELECT * FROM celulares
WHERE (MARCA = :marca )
AND (:categoria1,:categoria2,:categoria3)
IN (
(CATEGORIA,CATEGORIA2,CATEGORIA3),
(CATEGORIA,CATEGORIA3,CATEGORIA2),
(CATEGORIA2,CATEGORIA,CATEGORIA3),
(CATEGORIA2,CATEGORIA3,CATEGORIA),
(CATEGORIA3,CATEGORIA,CATEGORIA2),
(CATEGORIA3,CATEGORIA2,CATEGORIA)
)
This way you only pass in the categories once, and compare it against the six possible permutations of three categories.
That being said, this is a sign that your database is in very poor shape. Generally speaking having any kind of "column2", "column3" system is a sign that you need to restructure your database - the kind of queries you end up with, like the above, are only going to get worse.
Specifically, in this case, just adding CATEGORIEA4 would increase the amount of permutations you need to define from 6 to 24!!
EDIT: I completely missed the part about :marca and IN - I was too focussed on the bad state of the database with regard to categories, sorry!
Well, i fix it, probably it's not the best way to solve it but i have this now:
I fill array with entries from POST
$query = array();
$index = 0;
foreach ($_POST as $entrada) {
switch($entrada) {
case "SAMSUNG":
$query[] = "SAMSUNG";
break;
case "LG":
$query[] = "LG";
break;
case "APPLE":
$query[] = "APPLE";
break;
case "HUAWEI":
$query[] = "HUAWEI";
break;
}
}
$inQuery = str_repeat('?,', count($query) - 1) . '?';
Here's my new query: Problem was that i was mixing "?" with placeholders (:) which not is recommended
$statement = $conexion->prepare(
"SELECT * FROM celulares
WHERE ( MARCA IN($inQuery))
AND
(CATEGORIA = ? OR CATEGORIA = ? OR CATEGORIA = ?)
AND
(CATEGORIA2 = ? OR CATEGORIA2 = ? OR CATEGORIA2= ?)
AND
(CATEGORIA3 = ? OR CATEGORIA3 = ? OR CATEGORIA3 = ?)");
Then i bindValues like that
$c = 0;
foreach ($query as $q => $queries) {
$c++;
$statement->bindValue(($q+1), $queries);
}
$statement->bindValue($c+1, $categoria1);
$statement->bindValue($c+2, $categoria2);
$statement->bindValue($c+3, $categoria3);
$statement->bindValue($c+4, $categoria1);
$statement->bindValue($c+5, $categoria2);
$statement->bindValue($c+6, $categoria3);
$statement->bindValue($c+7, $categoria1);
$statement->bindValue($c+8, $categoria2);
$statement->bindValue($c+9, $categoria3);
$statement->execute();
$resultados = $statement->fetchAll();
I did many test with a lot of querys and it's working fine, probably it's a "dirty" solution but i'll continue learning
Thanks u all for helping me!
I have a problem. I want to json decode the API from https://www.easports.com/fifa/ultimate-team/api/fut/item?page=1, but this only contains 24 players and it has 771(!) pages so that will take forever if you do it one player at one. How can I do it all at once. I currently have this script:
<?php
$conn = mysqli_connect("localhost","u1715p547","L0yRM6pd","u1715p547_ps");
mysqli_set_charset($conn,"utf8");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$page_data_url = "https://www.easports.com/fifa/ultimate-team/api/fut/item?page=1";
// Get the JSON file from EASports
$page_data_plain = file_get_contents($page_data_url);
// Decode the JSON file to a PHP array
$page_data_json = json_decode($page_data_plain, true);
// Get the total pages count
$total_pages_count = $page_data_json['totalPages'];
// Loop through each page
for ($page = 1; $page <= $total_pages_count; $page++){
// Get the EASports JSON per specific page
$item_url = 'https://www.easports.com/fifa/ultimate-team/api/fut/item?page='.$page;
// Get the JSON file from EASports
$item_data_plain = file_get_contents($item_url);
// Decode the JSON file to a PHP array
$item_data_json = json_decode($item_data_plain, true);
// Count the amount of items
$total_items_count = $item_data_json['count'];
// Loop through all items, extract the values and insert in DB
for ($c = 0; $c < $total_items_count; $c++) {
$commonname00 = $item_data_json[$c]['commonName'];
$commonname = str_replace("'", "''", $commonname00);
$firstname00 = $item_data_json[$c]['firstName'];
$firstname = str_replace("'", "''", $firstname00);
$lastname00 = $item_data_json[$c]['lastName'];
$lastname = str_replace("'", "''", $lastname00);
$playerimg = $item_data_json[$c]['headshotImgUrl'];
$leagueid = $item_data_json[$c]['league']['id'];
$nationsmall = $item_data_json[$c]['nation']['imageUrls']['small'];
$nationnormal = $item_data_json[$c]['nation']['imageUrls']['medium'];
$nationlarge = $item_data_json[$c]['nation']['imageUrls']['large'];
$nationid = $item_data_json[$c]['nation']['id'];
$clubsmall = $item_data_json[$c]['club']['imageUrls']['normal']['small'];
$clubnormal = $item_data_json[$c]['club']['imageUrls']['normal']['medium'];
$clublarge = $item_data_json[$c]['club']['imageUrls']['normal']['large'];
$clubid = $item_data_json[$c]['club']['id'];
$largeImgUrl = $item_data_json[$c]['headshot']['largeImgUrl'];
$medImgUrl = $item_data_json[$c]['headshot']['medImgUrl'];
$smallImgUrl = $item_data_json[$c]['headshot']['smallImgUrl'];
$largeSpecImgUrl = $item_data_json[$c]['specialImages']['largeTOTWImgUrl'];
$medSpecImgUrl = $item_data_json[$c]['specialImages']['medTOTWImgUrl'];
$pos = $item_data_json[$c]['position'];
$ps = $item_data_json[$c]['playStyle'];
$heig = $item_data_json[$c]['height'];
$weig = $item_data_json[$c]['weight'];
$bd = $item_data_json[$c]['birthdate'];
$age = $item_data_json[$c]['age'];
$acc = $item_data_json[$c]['acceleration'];
$agg = $item_data_json[$c]['aggression'];
$agi = $item_data_json[$c]['agility'];
$bal = $item_data_json[$c]['balance'];
$ball = $item_data_json[$c]['ballcontrol'];
$foot = $item_data_json[$c]['foot'];
$sm = $item_data_json[$c]['skillMoves'];
$cro = $item_data_json[$c]['crossing'];
$cur = $item_data_json[$c]['curve'];
$dri = $item_data_json[$c]['dribbling'];
$fin = $item_data_json[$c]['finishing'];
$fca = $item_data_json[$c]['freekickaccuracy'];
$gkd = $item_data_json[$c]['gkdiving'];
$gkh = $item_data_json[$c]['gkhandling'];
$gkk = $item_data_json[$c]['gkkicking'];
$gkp = $item_data_json[$c]['gkpositioning'];
$gkr = $item_data_json[$c]['gkreflexes'];
$hea = $item_data_json[$c]['headingaccuracy'];
$int = $item_data_json[$c]['interceptions'];
$jum = $item_data_json[$c]['jumping'];
$lop = $item_data_json[$c]['longpassing'];
$los = $item_data_json[$c]['longshots'];
$mar = $item_data_json[$c]['marking'];
$pen = $item_data_json[$c]['penalties'];
$poi = $item_data_json[$c]['positioning'];
$pot = $item_data_json[$c]['potential'];
$rea = $item_data_json[$c]['reactions'];
$shp = $item_data_json[$c]['shortpassing'];
$sho = $item_data_json[$c]['shotpower'];
$slt = $item_data_json[$c]['slidingtackle'];
$spr = $item_data_json[$c]['sprintspeed'];
$stt = $item_data_json[$c]['standingtackle'];
$sta = $item_data_json[$c]['stamina'];
$str = $item_data_json[$c]['strength'];
$vis = $item_data_json[$c]['vision'];
$vol = $item_data_json[$c]['volleys'];
$wf = $item_data_json[$c]['weakFoot'];
$traits = $item_data_json[$c]['traits'][$c];
$traits1 = $item_data_json[$c]['traits']['1'];
$traits2 = $item_data_json[$c]['traits']['2'];
$traits3 = $item_data_json[$c]['traits']['3'];
$traits4 = $item_data_json[$c]['traits']['4'];
$specialities = $item_data_json[$c]['specialities'][$c];
$specialities1 = $item_data_json[$c]['specialities']['1'];
$specialities2 = $item_data_json[$c]['specialities']['2'];
$specialities3 = $item_data_json[$c]['specialities']['3'];
$specialities4 = $item_data_json[$c]['specialities']['4'];
$specialities5 = $item_data_json[$c]['specialities']['5'];
$specialities6 = $item_data_json[$c]['specialities']['6'];
$specialities7 = $item_data_json[$c]['specialities']['7'];
$specialities8 = $item_data_json[$c]['specialities']['8'];
$specialities9 = $item_data_json[$c]['specialities']['9'];
$specialities10 = $item_data_json[$c]['specialities']['10'];
$atk = $item_data_json[$c]['atkWorkRate'];
$def = $item_data_json[$c]['defWorkRate'];
$pty = $item_data_json[$c]['playerType'];
$pace = $item_data_json[$c]['attributes'][$c]['value'];
$shot = $item_data_json[$c]['attributes']['1']['value'];
$pass = $item_data_json[$c]['attributes']['2']['value'];
$drib = $item_data_json[$c]['attributes']['3']['value'];
$deff = $item_data_json[$c]['attributes']['4']['value'];
$phys = $item_data_json[$c]['attributes']['5']['value'];
$nameof00 = $item_data_json[$c]['name'];
$nameof = str_replace("'", "''", $nameof00);
$qua = $item_data_json[$c]['quality'];
$color = $item_data_json[$c]['color'];
$GK = $item_data_json[$c]['isGK'];
$posfull = $item_data_json[$c]['positionFull'];
$price = $item_data_json[$c]['discardValue'];
$id = $item_data_json[$c]['id'];
$baseId = $item_data_json[$c]['baseId'];
$rating = $item_data_json[$c]['rating'];
$sql = "INSERT IGNORE INTO `players`(`commonName`, `firstName`, `headshotImgUrl`, `lastName`, `leagueid`, `nationimageUrlssmall`, `nationimageUrlsmedium`, `nationimageUrlslarge`, `nationid`, `clubimageUrlsnormalsmall`, `clubimageUrlsnormalmedium`, `clubimageUrlsnormallarge`, `clubid`, `headshotlargeImgUrl`, `headshotmedImgUrl`, `headshotsmallImgUrl`, `specialImageslargeTOTWImgUrl`, `specialImagesmedTOTWImgUrl`, `position`, `playStyle`, `height`, `weight`, `birthdate`, `age`, `acceleration`, `aggression`, `agility`, `balance`, `ballcontrol`, `foot`, `skillMoves`, `crossing`, `curve`, `dribbling`, `finishing`, `freekickaccuracy`, `gkdiving`, `gkhandling`, `gkkicking`, `gkpositioning`, `gkreflexes`, `headingaccuracy`, `interceptions`, `jumping`, `longpassing`, `longshots`, `marking`, `penalties`, `positioning`, `potential`, `reactions`, `shortpassing`, `shotpower`, `slidingtackle`, `sprintspeed`, `standingtackle`, `stamina`, `strength`, `vision`, `volleys`, `weakFoot`, `traits0`, `traits1`, `traits2`, `traits3`, `specialities0`, `specialities1`, `specialities2`, `specialities3`, `specialities4`, `specialities5`, `specialities6`, `specialities7`, `specialities8`, `atkWorkRate`, `defWorkRate`, `playerType`, `attributes0value`, `attributes1value`, `attributes2value`, `attributes3value`, `attributes4value`, `attributes5value`, `name`, `quality`, `color`, `isGK`, `positionFull`, `discardValue`, `id`, `baseId`, `rating`, `specialities9`, `specialities10`, `traits4`)
VALUES ('$commonname', '$firstname', '$playerimg', '$lastname', $leagueid, '$nationsmall', '$nationnormal', '$nationlarge',
$nationid, '$clubsmall', '$clubnormal', '$clublarge', $clubid, '$largeImgUrl', '$medImgUrl',
'$smallImgUrl', '$largeSpecImgUrl', '$medSpecImgUrl', '$pos', '$ps', $heig, $weig, '$bd', $age, $acc, $agg, $agi, $bal, $ball, '$foot', $sm, $cro, $cur, $dri,
$fin, $fca, $gkd, $gkh, $gkk, $gkp, $gkr, $hea, $int, $jum, $lop, $los, $mar, $pen, $poi, $pot, $rea, $shp, $sho, $slt, $spr, $stt, $sta, $str, $vis, $vol, $wf,
'$traits', '$traits1', '$traits2', '$traits3', '$specialities', '$specialities1', '$specialities2', '$specialities3', '$specialities4', '$specialities5',
'$specialities6', '$specialities7', '$specialities8', '$atk', '$def', '$pty', $pace, $shot, $pass, $drib, $deff, $phys, '$nameof', '$qua', '$color', '$GK',
'$posfull', '$price', $id, $baseId, $rating, '$specialities9', '$specialities10', '$traits4')";
echo $sql;
if(!$result = $conn->query($sql))
{
die("<script type='text/javascript'>alert(Fault);</script>");
}
}
}
?>
It just gives me this:
INSERT IGNORE INTO `players`(`commonName`, `firstName`, `headshotImgUrl`, `lastName`, `leagueid`, `nationimageUrlssmall`, `nationimageUrlsmedium`, `nationimageUrlslarge`, `nationid`, `clubimageUrlsnormalsmall`, `clubimageUrlsnormalmedium`, `clubimageUrlsnormallarge`, `clubid`, `headshotlargeImgUrl`, `headshotmedImgUrl`, `headshotsmallImgUrl`, `specialImageslargeTOTWImgUrl`, `specialImagesmedTOTWImgUrl`, `position`, `playStyle`, `height`, `weight`, `birthdate`, `age`, `acceleration`, `aggression`, `agility`, `balance`, `ballcontrol`, `foot`, `skillMoves`, `crossing`, `curve`, `dribbling`, `finishing`, `freekickaccuracy`, `gkdiving`, `gkhandling`, `gkkicking`, `gkpositioning`, `gkreflexes`, `headingaccuracy`, `interceptions`, `jumping`, `longpassing`, `longshots`, `marking`, `penalties`, `positioning`, `potential`, `reactions`, `shortpassing`, `shotpower`, `slidingtackle`, `sprintspeed`, `standingtackle`, `stamina`, `strength`, `vision`, `volleys`, `weakFoot`, `traits0`, `traits1`, `traits2`, `traits3`, `specialities0`, `specialities1`, `specialities2`, `specialities3`, `specialities4`, `specialities5`, `specialities6`, `specialities7`, `specialities8`, `atkWorkRate`, `defWorkRate`, `playerType`, `attributes0value`, `attributes1value`, `attributes2value`, `attributes3value`, `attributes4value`, `attributes5value`, `name`, `quality`, `color`, `isGK`, `positionFull`, `discardValue`, `id`, `baseId`, `rating`, `specialities9`, `specialities10`, `traits4`) VALUES ('', '', '', '', , '', '', '', , '', '', '', , '', '', '', '', '', '', '', , , '', , , , , , , '', , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', , , , , , , '', '', '', '', '', '', , , , '', '', '')
You can't. You have to call it X times where X corresponds to number of pages.
You should ask authors if they could give you entire block of data in single call.
I'm trying to work out how to move the $sql_pay_det query outside of the $sql_pay loop (so in effect query on $rs_pay_det rather than creating a new $rs_pay_det for each iteration of the loop)
At the moment my code looks like:
//Get payroll transactions
$sql_pay = 'SELECT Field1, DescriptionandURLlink, Field5, Amount, Field4, PeriodName FROM tblgltransactionspayroll WHERE CostCentreCode = "'.$cc.'" AND SubjectiveCode = "'.$subj.'" AND PeriodNo = "'.$month.'"';
$rs_pay = mysql_query($sql_pay);
$row_pay = mysql_fetch_assoc($rs_pay);
while($row_pay = mysql_fetch_array($rs_pay))
{
$employee_name = $row_pay['Field1'];
$assign_no = $row_pay['DescriptionandURLlink'];
$pay_period = $row_pay['Field5'];
$mth_name = $row_pay['PeriodName'];
$amount = $row_pay['Amount'];
$total_amount = $total_amount + $amount;
$amount = my_number_format($amount, 2, ".", ",");
$sql_pay_det = 'SELECT ElementDesc, Amount, WTEWorked, WTEPaid, WTEContract, Payscale FROM tblpayrolldetail WHERE CostCentreCode = "'.$cc.'" AND SubjectiveCode = "'.$subj.'" AND AccountingPeriod = "'.$mth_name.'" AND EmployeeRef = "'.$assign_no.'"';
$rs_pay_det = mysql_query($sql_pay_det);
$row_pay_det = mysql_fetch_assoc($rs_pay_det);
while($row_pay_det = mysql_fetch_array($rs_pay_det))
{
$element_det = $row_pay_det['ElementDesc'];
$amount_det = $row_pay_det['Amount'];
$wte_worked = $row_pay_det['WTEWorked'];
$wte_paid = $row_pay_det['WTEPaid'];
$wte_cont = $row_pay_det['WTEContract'];
$payscale = $row_pay_det['Payscale'];
//Get band/point and annual salary where element is basic pay
if ($element_det =="3959#Basic Pay"){
$sql_payscale = 'SELECT txtPayscaleName, Salary FROM tblpayscalemapping WHERE txtPayscale = "'.$payscale.'"';
$rs_payscale = mysql_query($sql_payscale);
$row_payscale = mysql_fetch_assoc($rs_payscale);
$grade = $row_payscale['txtPayscaleName'];
$salary = "£" . my_number_format($row_payscale['Salary'], 0, ".", ",");
}
}
}
I've tried doing this:
//Get payroll transactions
$sql_pay = 'SELECT Field1, DescriptionandURLlink, Field5, Amount, Field4, PeriodName FROM tblgltransactionspayroll WHERE CostCentreCode = "'.$cc.'" AND SubjectiveCode = "'.$subj.'" AND PeriodNo = "'.$month.'"';
$rs_pay = mysql_query($sql_pay);
$row_pay = mysql_fetch_assoc($rs_pay);
//Get payroll detail recordset
$sql_pay_det = 'SELECT ElementDesc, Amount, WTEWorked, WTEPaid, WTEContract, Payscale, EmployeeRef FROM tblpayrolldetail WHERE CostCentreCode = "'.$cc.'" AND SubjectiveCode = "'.$subj.'" AND AccountingPeriod = "'.$mth_name.'"';
$rs_pay_det = mysql_query($sql_pay_det);
while($row_pay = mysql_fetch_array($rs_pay))
{
$employee_name = $row_pay['Field1'];
$assign_no = $row_pay['DescriptionandURLlink'];
$pay_period = $row_pay['Field5'];
$mth_name = $row_pay['PeriodName'];
$amount = $row_pay['Amount'];
$total_amount = $total_amount + $amount;
$amount = my_number_format($amount, 2, ".", ",");
//Query $rs_pay_det
$sql_pay_det2 = 'SELECT ElementDesc, Amount, WTEWorked, WTEPaid, WTEContract, Payscale FROM ('.$sql_pay_det.') tpd WHERE EmployeeRef = "'.$assign_no.'"';
$rs_pay_det2 = mysql_query($sql_pay_det2);
$row_pay_det2 = mysql_fetch_assoc($rs_pay_det2);
while($row_pay_det2 = mysql_fetch_array($rs_pay_det2))
{
$element_det = $row_pay_det2['ElementDesc'];
$amount_det = $row_pay_det2['Amount'];
$wte_worked = $row_pay_det2['WTEWorked'];
$wte_paid = $row_pay_det2['WTEPaid'];
$wte_cont = $row_pay_det2['WTEContract'];
$payscale = $row_pay_det2['Payscale'];
//Get band/point and annual salary where element is basic pay
if ($element_det =="3959#Basic Pay"){
$sql_payscale = 'SELECT txtPayscaleName, Salary FROM tblpayscalemapping WHERE txtPayscale = "'.$payscale.'"';
$rs_payscale = mysql_query($sql_payscale);
$row_payscale = mysql_fetch_assoc($rs_payscale);
$grade = $row_payscale['txtPayscaleName'];
$salary = "£" . my_number_format($row_payscale['Salary'], 0, ".", ",");
}
}
}
But I get an error on $row_pay_det2 saying that "mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource"
Your subquery syntax (... FROM "'.$rs_pay_det.'" ...) is wrong.
According to the manual - dev.mysql.com/doc/refman/5.0/en/from-clause-subqueries.html
Subqueries are legal in a SELECT statement's FROM clause. The actual
syntax is:
SELECT ... FROM (subquery) [AS] name ...
Try changing to-
$sql_pay_det2 = 'SELECT ElementDesc, Amount, WTEWorked, WTEPaid, WTEContract, Payscale FROM ('.$sql_pay_det.') tpd WHERE EmployeeRef = "'.$assign_no.'"';
Edit - Issue #2
You are only getting the 2nd row in your data set as you have duplicate code (mysql_fetch_assoc() & mysql_fetch_array()) that moves the internal data pointer ahead after the using mysql_fetch_assoc(). So when you do mysql_fetch_array() you will get every row except the 1st row.
//Get payroll transactions
...
$row_pay = mysql_fetch_assoc($rs_pay);
//Get payroll detail recordset
...
while($row_pay = mysql_fetch_array($rs_pay))
{
...
$row_pay_det2 = mysql_fetch_assoc($rs_pay_det2);
while($row_pay_det2 = mysql_fetch_array($rs_pay_det2))
{
...
}
}
}
You need to remove - $row_pay = mysql_fetch_assoc($rs_pay); & $row_pay_det2 = mysql_fetch_assoc($rs_pay_det2);