I am having trouble with an SQL query that I have inserted into a piece of PHP code to retrieve some data. The query itself works perfectly within SQL, but when I use it within my PHP script it says "Error in Query" then recites the entire SQL statement. If I copy and paste the SQL statement from the error message directly into MySQL it runs with no errors.
From my research I believe I am missing an apostrophe somewhere, so PHP may be confusing the clauses, but I am not experienced enough to know where to insert them.
The query is using a variable called $userid which is specified earlier in the PHP script.
$sql= <<<END
SELECT sum(final_price)
FROM (
SELECT Table_A.rated_user_id, Table_B.seller, Table_B.final_price
FROM Table_A
INNER JOIN Table_B ON Table_A.id=Table_B.id
) AS total_bought
WHERE seller != $userid
AND rated_user_id = $userid
UNION ALL
SELECT sum(final_price)
FROM (
SELECT Table_A.rated_user_id, Table_C.seller, Table_C.final_price
FROM Table_A
INNER JOIN Table_C ON Table_A.id=Table_C.id
) AS total_bought
WHERE seller != $userid
AND rated_user_id = $userid
END;
After this section the script then goes on to define the output and echo the necessary pieces as per usual. I'm happy with the last part of the code as it works elsewhere, but the problem I am having appears to be within the section above.
Can anyone spot the error?
Edited to add the following additional information:
All of the fields are numerical values, none are text. I have tried putting '$userid' but this only makes the error display the ' ' around this value within the error results. The issue remains the same. Adding parenthasis has also not helped. I had done a bit of trial and erorr before posting my question.
If it helps, the last part of the code bieng used is as follows:
$result = mysql_query($sql);
if (!$res) {
die('Error: ' . mysql_error() . ' in query ' . $sql);
}
$total_bought = 0;
while ($row = mysql_fetch_array($result)) {
$total_bought += $row[0];
}
$total_bought = number_format($total_bought, 0);
echo '<b>Your purchases: ' . $total_bought . '</b>';
echo "<b> gold</b>";
You're checking !$res, it should be !$result:
$result = mysql_query($sql);
if (!$result) {
die('Error: ' . mysql_error() . ' in query ' . $sql);
}
I suppose, you're echo()ing the query somewhere and copy-pasting it from the browser. Could it be that the $userid contains xml tags? They wouldn't be displayed in the browser, you would have to view the page source to spot them.
you should test with $userid quoted, and parentheses around the two statements.
I'm assuming that rated_user_id is a numeric field, but what type is seller? If it's a character field, then $userid would have to be quoted as streetpc suggests.
Another thing to check is that you have at least one space after the end of your lines for each line of the query. That has tripped me up before. Sometimes when going from your editor/IDE to the database tool those problems are silently taken care of.
Related
I am beginner and I am trying update tables in Joomla (3.8) database and I get 504 Gateway Time-out nginx error at the following sql query:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$condition = array(
$db->quoteName('B.virtuemart_product_id') . ' >= '.$product_id_from,
$db->quoteName('B.virtuemart_product_id') . ' <= '.$product_id_to);
$query->select(array('B.virtuemart_product_id, A.product_sku,
A.price_CZK, A.price_EUR'))
->from($db->quoteName('#__watrex_price_list_temp', 'A'))
->join('INNER' , $db->quoteName('#__virtuemart_products', 'B') . '
ON (' . $db->quoteName('B.product_sku') . ' = ' . $db-
>quoteName('A.product_sku') . ')')
->where($condition,'AND');
$db->setQuery($query);
$num_rows = $db->getNumRows();
$results = $db->loadObjectList();
...
Result can contain up to 50000 items. How can I fix this problem? Thank you
I suspect that getNumRows() is the culprit here. When I run call echo $db->getNumRows() on my localhost with a successful query returning a non-empty result set to replicate the issue, I get:
Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, null given in C:\wamp64\www\blah\libraries\joomla\database\driver\mysqli.php on line ###
NULL
To fix this, add $db->execute(); on the line before $db->getNumRows() and everything works happily and as desired. That said, I recommend just calling count() or sizeof() on $results because you'll get the same output without having to add the execute() call.
If that isn't the cause, this may or may not be within your control. You may wish to work through this checklist of advice: https://www.lifewire.com/504-gateway-timeout-error-explained-2622941
As for how to process your result set with less memory consumption, you might entertain James Garrett's suggestion.
As for subtle refinements to your query:
Your SELECT clause renders appropriately, but the syntax seems to be designed with the intent to create an array of columns. Truth is, you have a single-element array containing all four columns. This only becomes problematic if you decide to apply quoteName() to the array.
I recommend lowercase table aliases so that they do not "catch the eye" as MySQL keywords. SQL Queries - Paragraph 1
The ON declaration doesn't need to be parenthetically wrapped.
None of your tables or columns actually need quoteName() to be called on them to maintain stability/security. You may choose to omit them to make your code easier to read, but the Joomla coding standards demand 100% employment of the call (I personally dislike this stance). SQL Queries - Paragraph 5
Table names and table column names should always be enclosed in the quoteName() method to escape the table name and table columns.
It may not aid in performance, but BETWEEN is "inclusive" and is specifically designed to do what your two WHERE conditions require. https://www.techonthenet.com/mysql/between.php
My recommended snippet:
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName(["b.virtuemart_product_id", "a.product_sku", "a.price_CZK", "a.price_EUR"]))
->from($db->quoteName("#__watrex_price_list_temp", "a"))
->innerJoin($db->quoteName("#__virtuemart_products", "b") . " ON " . $db->quoteName('b.product_sku') . " = " . $db>quoteName("a.product_sku"))
->where($db->quoteName("b.virtuemart_product_id") . " BETWEEN " . (int)$product_id_from . " AND " . (int)$product_id_to);
$db->setQuery($query);
if (!$results = $db->loadObjectList()) {
echo "No Rows";
} else {
// if you need to know the count...
echo count($results);
// iterate the result set
foreach ($results as $row) {
// ... yatta-yatta ...
}
}
If ALL of the above fails, I recommend a re-think of your project. Perhaps you should be reducing the result set volume with LIMIT and using pagination techniques if necessary.
p.s. Rick James has some excellent advice about adding indexes.
I've been trying to make this code work for hours now but I can't seem to find solution. I've serached all relevant topics and tried to change the code, punctuation etc. but none of them worked for me.
The result is always "Success!" but the database update never works (checked in phpmyadmin).
I hope that you can find the error. The code is the following:
if(empty($_POST['nev']) || empty($_POST['orszag']) || empty($_POST['telefonszam']) || empty($_POST['iranyitoszam'])
|| empty($_POST['megye']) || empty($_POST['varos']) || empty($_POST['utca'])) {
echo "Failure! Missing data...";
}
else {
$nev = mysql_real_escape_string($_POST['nev']);
$orszag = mysql_real_escape_string($_POST['orszag']);
$telefonszamm = mysql_real_escape_string($_POST['telefonszam']);
$iranyitoszam = mysql_real_escape_string($_POST['iranyitoszam']);
$megye = mysql_real_escape_string($_POST['megye']);
$varos = mysql_real_escape_string($_POST['varos']);
$utca = mysql_real_escape_string($_POST['utca']);
$shipping_query = mysql_query("UPDATE users
SET Name=".$nev.", Phone=".$telefonszam.",
Country=".$orszag.", State=".$megye.",
City=".$varos.", ZIP=".$iranyitoszam.",
Road=".$utca."
WHERE EmailAddress='" . $_SESSION['EmailAddress'] . "'");
echo "Success!";
}
Thank you for your help!
You're missing quotes around the strings in your query.
$shipping_query = mysql_query("UPDATE users
SET Name='".$nev."', Phone='".$telefonszam."',
Country='".$orszag."', State='".$megye."',
City='".$varos."', ZIP='".$iranyitoszam."',
Road='".$utca."'
WHERE EmailAddress='" . $_SESSION['EmailAddress'] . "'");
You also no error checking on your query. So whether it succeeds or fails it will always say, "success". You need to check to see if there is a MySQL error ir rows updated before you can declare success.
Name, Phone, Country etc etc seam like VARCHARs. so, it should be treated as a string.
So, query should be like.
"UPDATE users SET Name='".$nev."', Phone='".$telefonszam."',Country='".$orszag."', State='".$megye."',City='".$varos."', ZIP='".$iranyitoszam."',Road='".$utca."' WHERE EmailAddress='" . $_SESSION['EmailAddress'] . "'"
As other answers have pointed out, you're missing quotes around your string variables.
When you're MySQL queries are failing to execute, try echoing your queries while debugging to see what exactly you're sending to the database.
$myValue = "Green";
$mySQL = "UPDATE MyTable SET MyColor = " . $myValue;
$myQuery = mysql_query($mySQL);
echo $mySQL;
Spotting the error visually is much easier when the entire SQL string is assembled in one piece.
You can also copy the assembled SQL string and paste it straight into a phpmyadmin query to get debugging information from it.
Hi I'm trying to run the following query but nothing seems to be returned
All I want to is to return the job_discription for the choosen job_type from my jobs table.
Please any help would be great as I have spent hours trying to solve it.
Thank you
alan
<input type="hidden" name="JOB_TYPE" value="<?php print $_POST['JOB_TYPE'];?>"/>
<?php
$Query = " (SELECT JOB_TYPE, JOB_DISCRIPTION FROM jobs " .
"WHERE jobs.JOB_TYPE ='$_POST[JOB_TYPE]' " .
"AND jobs.JOB_DISCRIPTION = 'JOB_DISCRIPTION')";
$Result = mysqli_query($DB, $Query);
?>
<?php
$Result = mysqli_query($DB,$Query)or die(mysqli_error($DB));
while ($Row = mysqli_fetch_assoc($Result)) // Now we go through the data displaying
{
print $Row ['JOB_DISCRIPTION'] ;
}
?>
First, the code is very prone to sql injection: you shouldn't use the $_POST data directly. Second remove the last condition if you want a description for a particular type.
Remove the AND statement from the end:
AND jobs.JOB_DISCRIPTION = 'JOB_DISCRIPTION'
Also remove the parenthesis ( ) from around the query statement.
" -- quotation marks are only required at the start and end
SELECT JOB_TYPE
, JOB_DISCRIPTION -- some people spell description with an 'e'
FROM jobs
WHERE jobs.JOB_TYPE =$_POST['JOB_TYPE'] -- escape data (using modern methods) to prevent injection and note
AND jobs.JOB_DISCRIPTION = 'JOB_DISCRIPTION'; -- This is really strange
"
HI everyone i tried for 3 days and i'm not able to solve this problem. This is the codes and i have went through it again and again but i found no errors. I tried at a blank page and it worked but when i put it inside the calendar it has the syntax error. Thanks a million for whoever who can assist.
/** QUERY THE DATABASE FOR AN ENTRY FOR THIS DAY !! IF MATCHES FOUND, PRINT THEM !! **/
$testquery = mysql_query("SELECT orgid FROM sub WHERE userid='$userid'");
while($row4 = mysql_fetch_assoc($testquery))
{
$org = $row4['orgid'];
echo "$org<br>";
$test2 = mysql_query("SELECT nameevent FROM event WHERE `userid`=$org AND EXTRACT(YEAR FROM startdate)='2010' AND EXTRACT(MONTH FROM startdate)='08' AND EXTRACT(DAY FROM startdate)='15'") or die(mysql_error());
while($row5=mysql_fetch_assoc($test2))
{
$namethis = $row5['nameevent'];
$calendar.=$namethis;
}
}
First question: what calendar are you talking about?
And here are my 2-cents: does the EXTRACT function returns a string or a number?
Are the "backticks" (userid) really in your query? Try to strip them off.
Bye!
It's a guess, given that you haven't provided the error message you're seeing, but I imagine that userid is a text field and so the value $org in the WHERE clause needs quotes around it. I say this as the commented out testquery has quotes around the userid field, although I appreciate that it works on a different table. Anyway try this:
SELECT nameevent FROM event WHERE userid='$org' AND EXTRACT(YEAR FROM startdate)='2010' AND EXTRACT(MONTH FROM startdate)='08' AND EXTRACT(DAY FROM startdate)='15'
In such cases it's often useful to echo the sql statement and run it using a database client
First step in debugging problems like this, is to print out the acutal statement you are running. I don't know PHP, but can you first build up the SQL and then print it before calling mysql_query()?
EXTRACT() returns a number not a character value, so you don't need the single quotes when comparing EXTRACT(YEAR FROM startdate) = 2010, but I doubt that this would throw an error (unlike in other databases) but there might be a system configuration that does this.
Another thing that looks a bit strange by just looking at the names of your columns/variables: you are first retrieving a column orgid from the user table. But you compare that to the userid column in the event table. Shouldn't you also be using $userid to retrieve from the event table?
Also in the first query you are putting single quotes around $userid while you are not doing that for the userid column in the event table. Is userid a number or a string? Numbers don't need single quotes.
Any of the mysql_* functions can fail. You have to test all the return values and if one of them indicates an error (usually when the function returns false) your script has to handle it somehow.
E.g. in your query
mysql_query("SELECT orgid FROM sub WHERE userid='$userid'")
you mix a parameter into the sql statement. Have you assured that this value (the value of $userid) is secure for this purpose? see http://en.wikipedia.org/wiki/SQL_injection
You can use a JOIN statement two combine your two sql queryies into one.
see also:
http://docs.php.net/mysql_error
http://docs.php.net/mysql_real_escape_string
http://www.w3schools.com/sql/sql_join.asp
Example of rudimentary error handling:
$mysql = mysql_connect('Fill in', 'the correct', 'values here');
if ( !$mysql ) { // some went wrong, error hanlding here
echo 'connection failed. ', mysql_error();
return;
}
$result = mysql_select_db('dbname', $mysql);
if (!$result ) {
echo 'select_db failed. ', mysql_error($mysql);
return;
}
// Is it safe to use $userid as a parmeter within an sql statement?
// see http://docs.php.net/mysql_real_escape_string
$sql = "SELECT orgid FROM sub WHERE userid='$userid'";
$testquery = mysql_query($sql, $mysql);
if (!$testquery ) {
echo 'query failed. ', mysql_error($mysql), "<br />\n";
echo 'query=<pre>', $sql, '</pre>';
return;
}
I have this bit of code:
//Restrict the SQL query with an AND clause if a member has been selected
if ($form_member_id != 0) {
$query .= "AND photos.member_id = '$form_member_id' ";
}
It is meant to refine a search query down to only the selected user, so the whole query together reads:
SELECT
photos.photo_id, members.member_name, photos.photo_title, photos.photo_film, photos.photo_height, photos.photo_width
FROM members, photos
WHERE members.member_id = photos.member_id
AND photos.member_id = '$form_member_id'
For some reason this does not work, ive tested the query and it works fine, but for some reason it wont work with the code ive written. I've checked for difference in the names of the variables but they are all the same....anyone know why its not working!!!
I think that you need a space before your AND otherwise it will be:
WHERE members.member_id = photos.member_idAND photos.member_id = '$form_member_id'
instead of
WHERE members.member_id = photos.member_id AND photos.member_id = '$form_member_id'
Ditto what #Matthew says about using parameterized queries, but I still think the above is the issue.
Obvious step is to print the full query before running it, then run it manually and see what happens. Also, you should be using prepared statements.
debug the script using
if ($form_member_id != 0) {
$query .= "AND photos.member_id = '$form_member_id' ";
die($query);
}
copy and paste the query and run it in phymyadmin or etc to figure out the source of bug
for better security, you may want it to be like this
if ($form_member_id != 0) {
$query .= "AND photos.member_id = '" . mysql_real_escape_string($form_member_id) . "' ";
}
You should echo the query if its now working for you to see what seems to be the problem :)
One other thing, and I'm not experienced with php, but your code looks prime-target for SQL-Injection attacks...
Someone could stuff the buffer for your "$form_member_id" and put in a value like
'; truncate members; '
where the leading and trailing quote are part of the submitted string... the first '; will terminate your string, ; to end a statement, and then truncate your table and ignore the rest...
Again, I'm not a PHP person, but so many other historical security postings talk about PARAMETERIZING your queries to prevent such injection attacks