Whats wrong with this SQL query? - php

I haven't been writing PHP/SQL in a few years and needed to do this for a project. And now I have run into a problem.
I wanting to grab some data from a MySQL databas, between specific dates. It works just fine if write it like this:
$result = mysql_query("SELECT * FROM acw WHERE team = '".$team."' and added between '2012-11-05' and '2012-11-10' ");
But I want to get the dates from the URL, and have written this:
$periods = $_GET["per"];
if ( $periods == 1 ) {
$period = "and added between '2012-11-05' and '2012-11-10'";
}
elseif ( $periods == 2 ) {
$period = "and added between '2012-11-11' and '2012-11-17'";
}
elseif ( $periods == 3 ) {
$period = "and added between '2012-11-05' and '2012-11-10'";
}
echo $period;
If I echo $period I got the correct output in the HTML but when trying to insert it to my MySQL questions i got nothing, what does I do wrong?
$result = mysql_query("SELECT * FROM acw WHERE team = '".$team."' '".$period."' ");
So something is wrong with this, and can't solve it by my self :(

Your string in $period is a full chunk of SQL, not a quoted string literal. So remove the single quotes surrounding it.
$result = mysql_query("SELECT * FROM acw WHERE team = '". $team ."' " . $period);
//---------------No quotes here----------------------------------------^^^^^^^^^^
Note: We assume that $team, if originating from user input, has already been properly escaped against SQL injection via mysql_real_escape_string()
It is recommended to always debug your SQL statement by echo'ing out the string. It would have been a little more obvious to see a string like:
SELECT * FROM acw WHERE team = 'The Team' 'and added between '2012-11-05' and '2012-11-10''
A final word of advice - unless this is already done in code not posted here, verify that $_GET['per'] is set before attempting to use it:
// Set $periods to the $_GET value or defualt to 1 if it isn't set (or whatever value)
$periods = isset($_GET["per"]) ? $_GET['per'] : 1;

Related

SQL query not working but works in PHPMyAdmin

I have a web application and I'm trying to modify one of the queries. The query fetches information (from a table named voyage_list) and returns various fields.
I want to modify the query so that it is based on certain filters the user applies (which will be placed in the URL).
I can't get the query to work in the web application, but if I copy the query and execute it directly within PHPMyAdmin, it works fine.
$vesselFilter = $_GET['vesselFilter'];
$vesselArray = explode(',', $vesselFilter);
$arrayCount = count($vesselArray);
$sqlExtend = ' status = 1 AND';
foreach ($vesselArray as $value) {
$i = $i + 1;
$sqlExtend .= " vesselID = '$value'";
if ($i < $arrayCount){
$sqlExtend .= " OR";
}
}
$newQuery = "SELECT * FROM voyage_list WHERE" . $sqlExtend;
echo $newQuery;
$query = $db->query($newQuery)->fetchAll();
I appreciate the above is pretty messy, but it's just so I can try and figure out how to get the query to work.
Any help would be greatly appreciated!
Thanks
That query probably doesn't return what you think it does. AND takes precedence over OR, so it will return the first vessel in the list if the status is 1, and also any other vessel in the list, regardless of status.
You'd do better to create a query with an IN clause like this:
SELECT * FROM voyage_list WHERE status = 1 AND vesselID IN(8,9,10)
Here's some code to do just that:
$vesselFilter = $_GET['vesselFilter'];
// Validate data. Since we're expecting a string containing only integers and commas, reject anything else
// This throws out bad data and also protects against SQL injection.
if (preg_match('/[^0-9,]/', $vesselFilter)) {
echo "Bad data in input";
exit;
}
// filter out any empty entries.
$vesselArray = array_filter(explode(',', $vesselFilter));
// Now create the WHERE clause using IN
$sqlExtend = 'status = 1 AND vesselID IN ('.join(',', $vesselArray).')';
$newQuery = "SELECT * FROM voyage_list WHERE " . $sqlExtend;
echo $newQuery;
$query = $db->query($newQuery)->fetchAll();
var_dump($query);

PHP String Manipulation and SQL Query

Hi still a beginner in php programming and one of the function of my project is to check if the schedule exist or not in the database. anyway my problem is that the way i created the string query, i am not sure if the string is correct in terms of syntax but the query is correct and tested in the phpmyadmin MySQL GUI.
$start_time = $_POST['Time-In'];
$end_time = $_POST['Time-Out'];
$procedure_date = $_POST['txbDateofProcedure'];
$DateStartTime = $procedure_date." ".$start_time;
$DateEndTime = $procedure_date." ".$end_time;
//Not sure but i think that the $Check-Schedule php syntax is incorrect
$Check_Schedule = "select * from appointment_dim where dentist_id = '$dentist_id'".
"and (CONCAT(appoint_date, ,appoint_timein) between '$DateStartTime' and '$DateEndTime')".
"OR (CONCAT(appoint_date, ,appoint_timeout) between '$DateStartTime' and '$DateEndTime')";
$result_schedule = mysql_query($Check_Schedule,$con);
if(!$result_schedule)
{
trigger_error("Cannot located database".mysql_error());
die();
}
if(mysql_num_rows($result_schedule) > 0)
{
$SchedErrMesg = "The time you requested is already take try again.";
echo"<script type='text/javascript'>alert('$SchedErrMesg');</script>";
die();
}
if you want the delimiter between appoint_date and appoint_time* to be space, you should do this:
CONCAT(appoint_date, ' ', appoint_timein)
but not this:
CONCAT(appoint_date, , appoint_timein)
Also i believe u want the logic like
"dentist_id = x AND (timeBetween1 OR timeBetween2)"
But not that u wrote:
"(dentist_id = x AND timeBetween1) OR timeBetween2"
So try this:
$Check_Schedule = "
SELECT * FROM appointment_dim
WHERE
dentist_id = '$dentist_id'
AND (
(CONCAT(appoint_date, ' ', appoint_timein) BETWEEN '$DateStartTime' AND '$DateEndTime')
OR (CONCAT(appoint_date, ' ', appoint_timeout) BETWEEN '$DateStartTime' AND '$DateEndTime')
)
";

Issues using between, min and max

I have created a catalog with a block of years search function for characters and the years I've assigned to them. So anything from 1940-1949 would be in the 1940's block of time, and so on. I'm using a href to group these timeframes.
<?php
$sql = "SELECT * FROM catalog";
$displayby = $_GET['displayby'];
$displayvalue = $_GET['displayvalue'];
if($displayby && $displayvalue){
$sql = "SELECT * FROM catalog WHERE $displayby LIKE '$displayvalue'";
}
if($displayby == 'year'){
$min = $_GET['min'];
$max = $_GET['max'];
$sql = "SELECT * FROM catalog WHERE year BETWEEN '$min' AND '$max'";
}
//$result = mysqli_query($con,$sql);
$result = mysqli_query($con,"SELECT * FROM catalog WHERE year BETWEEN '$min' AND '$max'");
while($row = mysqli_fetch_array($result)){
$name = $row['name'];
$filename = $row['filename'];
$cid = $row['cid'];
echo "\n<div class=\"holder\">";
echo "<img src=\"thumbs/$filename\">";
echo "$name<br />\n";
echo "</div>";
}
?>
With this href to only bring up certain characters within those years:
40's Villans<br/>
However they are showing up in the years prior - it might be 1945 as a set date for the character but they only appear in 1930's link.
What am i doing wrong?
Edit : here is the table
BETWEEN ... AND .... can be used for integers and strings. so:
BETWEEN 1 AND 3
Will be true for 1, 2 and 3. But:
BETWEEN 'a' AND 'c'
Will be true for 'a', 'b' and 'c'.
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_between
You've put quotes around your numbers, turning them into strings. So the comparison is done on the characters, not the numbers.
Removing the quotes should make it work.
$result = mysqli_query($con,"SELECT * FROM catalog WHERE year BETWEEN $min AND $max");
But as said by others, there are a lot of other problems with the code. This mistake is a symptom of someone who doesn't really know what they're doing. Why not start at the beginning, and grab a good book. Read it. Do the examples. Experiment. It can take years to become a fluent programmer. (This is meant as an ecouragement, not critizm.)
instead of using between you can also use the following statement for getting the desired data as following
$sql = "SELECT * FROM catalog WHERE year >= '$min' AND year <='$max'";
and in phpmyadmin you can run the query to make sure that you are getting the correct data ,and after that you can check your code where you are displaying it
i hope it help's you..

Mysql results duplicated even though the query does not match

apologize firstly for my questionable coding in php/mysql however this is all self taught (possibly not best practice)
All my code seems to work , however when the results are written to the page any $dxcall that is not in the $qrzdata database gets filled with the last result all other data displays fine. I have tried changing the like $dxcall to = $dxcall. I have also tried combining the fetch arrays too incase my issues was there too. But clearly my code does not know how to handle where there is not data match in the qrzdata database and to move on.
$frqry is the main data, all the other mysql_query's be it the $squares and $qrzdata are matching what comes from $frqry. Hope this makes sense !!
Here is my code
$frqry = mysql_query("select * from spots where freq between '69900' and '70300' ORDER BY datetime desc limit 30");
While ($r0 = mysql_fetch_array($frqry))
{
$freq = $r0["freq"];
$dxcall = $r0["dxcall"];
$datetime = $r0["datetime"];
$comments = $r0["comments"];
$spotter = $r0["spotter"];
$dt = date('d-m-y H:i ', $datetime);
$qra = $r0["loc"];
$squares = mysql_query("select * from squares where callsign like '$dxcall' limit 1");
while ($r1 = mysql_fetch_array($squares))
{
$qra = $r1["loc"];
}
$qrzdata = mysql_query("select * from qrzdata where callsign = '".$dxcall."' limit 1");
While ($r2 = mysql_fetch_array($qrzdata))
{
$country = $r2["country"];
$firstname = $r2["firstname"];
$city = $r2["city"];
}
Any help is greatly appreciated. Thank you.
You need to learn about the power of the JOIN ;)
Your whole code could be rewritten in one single query :
disclaimer: not tested, but you certainly get the idea
SELECT * FROM spots
JOIN squares ON (squares.callsign = spots.dxcall) -- this comes in stead of your first inner loop
JOIN qrzdata ON (qrzdata.callsign = spots.dxcall) -- this is your second loop
WHERE freq BETWEEN 69900 AND 70300 -- remove quotes, you are dealing with integers, not strings (hopefully)
You have to reset your vars!
While ($r0 = mysql_fetch_array($frqry))
{
$qra = '';
$country = '';
$firstname = '';
$city = '';
or you will allways get the last value

Passing multiple $_POST fields through MySQL search query

I have a search form with a possible 15 or so fields, however not all are required to carry out a search, for instance;
a user might search for a registered user in 'London' who works in 'Finance' but leave all other fields blank, such as $availability or $salary etc, so $_POST data may look something like:
$location = $_POST['location']; // Value - London
$sector = $_POST['sector']; // Value - Finance
$available = $_POST['available']; // Value - Any
$salary = $_POST['salary']; // Value - Any
Bearing in mind I may have another 12 or so 'Any' values from other fields, what is the best way to query the database (PHP/MySQL) to return results without looping through what would probably be dozens of queries.
To try and be a bit clearer, what i'd like is a query which would work something like (deliberate pseudo code):
SELECT * FROM table where location = 'location' AND if($availability !='Any') { available = '$available' } etc etc
Is something like this possible?
Or can I create a single string of all $_POST fields that !='Any' and then carry out a search on a row that contains all the words in the string (which I think would work in theory)?
I hope this makes sense to someone and you can point me in the right direction.
P.S. All $_POST is escaped and secured before interacting with database, just not included here :)
Try this:
$sql = "SELECT * FROM table where 1 ";
foreach ($_POST as $key => $post) {
if ($post != 'Any') {
$sql .= " AND $key = '$post' ";
}
}
// now you can run $sql against the database
Could you for argument sake collect all of the $_POST into a foreach($key=>$val) and then run the key through a switch or if statments that appends "AND x=x " to the statement?
Something like:
$sql = "SELECT * FROM table WHERE required='required'";
foreach($_POST as $key=>$val){
if(!empty($val)){ $sql .= " AND ".$key."='".$val"'"; }
}
Not sure if that works but in theory that is what i thought of first.
Thanks to those who offered answers, however I used the suggested answer found in the link above my question as it was clearer to me. Sample code pasted below FYI:
$tmp = "where ";
if($A and $A!="any" and $A!="not used")
$tmp .= "row1 = '".$A."'";
if($B and $B!="any" and $B!="not used")
$tmp .= "AND row2 = '".$B. "'";
if($C and $C!="any" and $C!="not used")
$tmp .= "AND row3 = '".$C."'";
$db_q = "Select * from table $tmp";
Thanks again, don't know where I'd be without SO.

Categories