PDO LIKE query not returning results - php

Well, I've been at this for a few hours, and for the life of me I can't figure out what is wrong. The code is as follows:
$str = "%" . $_POST['str'] . "%";
$offset = (int) $_POST['offset'];
try {
$stmt = $dbh->prepare("SELECT * FROM Spells WHERE :col LIKE :str ORDER BY :sort LIMIT 10 OFFSET :offset");
$stmt->bindParam(":col",$_POST['col']);
$stmt->bindParam(":str",$str);
$stmt->bindParam(":offset",$offset, PDO::PARAM_INT);
$stmt->bindParam(":sort",$_POST['sort']);
$stmt->execute();
}
catch (PDOException $e) {
echo "MySQL error: " . $e->getMessage() . "<br/>";
die();
}
The connection to the database works fine, no errors occur. If I type in % into the search field(which would be output as %%% in the query), results return as expected.
I've attempted the same query in phpMyAdmin and it works fine. I've been updating this script from the deprecated mysql_* functions, which worked fine before.
Example of the previous, deprecated query:
$sql = "SELECT * FROM Spells WHERE " . $col . " LIKE '%" . $str . "%' ORDER BY " . $sort . " LIMIT 10 OFFSET " . $offset;
As I may have already stated, I've been searching on this site as well, trying to find a solution; nothing has worked, not even MySQL's CONCAT('%',:str,'%').
The server I'm testing this on is running off of php version 5.3.17.
My question, in case I did not make it clear, is what am I doing wrong here? For those wondering(I thought that I put this but apparently I did not), there are no error messages.

The issue is that you cannot use parameters in place of identifiers. This means you cannot parameterise column or table names.
What your query essentially looks like when it is executed is
SELECT * FROM Spells WHERE 'some_column_name' LIKE '%something%'...
I would establish a whitelist of search and sort column names and use those to construct your query. Here's a very simple example
$search = array('col1', 'col2', 'col3');
$defaultSearch = 'col1';
$sort = array('col1', 'col2');
$defaultSort = 'col1';
$col = in_array($_POST['col'], $search) ? $_POST['col'] : $defaultSearch;
$sort = in_array($_POST['sort'], $sort) ? $_POST['sort'] : $defaultSort;
$sql = sprintf('SELECT * FROM Spell WHERE %s LIKE :str ORDER BY %s LIMIT 10 OFFSET :offset',
$col, $sort);
$stmt = $dbh->prepare($sql);
// bind :str and :offset, and so on

Related

Why i am getting datatype mismatch error?

SQLSTATE[42804]: Datatype mismatch: 7 ERROR: argument of WHERE must be
type boolean, not type integer LINE 1
$sql = "SELECT mod_modulegroupcode, mod_modulegroupname FROM module "
. " WHERE 1 GROUP BY `mod_modulegroupcode` "
. " ORDER BY `mod_modulegrouporder` ASC, `mod_moduleorder` ASC ";
$stmt = $DB->prepare($sql);
$stmt->execute();
$commonModules = $stmt->fetchAll();
$sql = "SELECT mod_modulegroupcode, mod_modulegroupname, mod_modulepagename, mod_modulecode, mod_modulename FROM module "
. " WHERE 1 "
. " ORDER BY `mod_modulegrouporder` ASC, `mod_moduleorder` ASC ";
$stmt = $DB->prepare($sql);
$stmt->execute();
$allModules = $stmt->fetchAll();
$sql = "SELECT rr_modulecode, rr_create, rr_edit, rr_delete, rr_view FROM role_rights "
. " WHERE rr_rolecode = :rc "
. " ORDER BY `rr_modulecode` ASC ";
$stmt = $DB->prepare($sql);
$stmt->bindValue(":rc", $_SESSION["rolecode"]);
$stmt->execute();
$userRights = $stmt->fetchAll();
You are getting a datatype mismatch error because the where clause of a SQL statement expects you to provide conditions, not integer values. Your third query has a condition for its where clause, but your first two try to just give an integer value. There are some programming languages where 1 treated like "true", but SQL is not one of those languages.
Given that you're assembling the SQL with your code, if there's no condition to provide for the where clause, then just leave the where clause out, like this:
$sql = "SELECT mod_modulegroupcode, mod_modulegroupname FROM module "
. " GROUP BY `mod_modulegroupcode` "
. " ORDER BY `mod_modulegrouporder` ASC, `mod_moduleorder` ASC ";
But then you're going to have a problem because mod_modulegroupname is not aggregated. Since you're not doing any aggregation, I suggest just taking the GROUP BY clause out, too. You should also take the backticks out of your order by. This would leave you with:
$sql = "SELECT mod_modulegroupcode, mod_modulegroupname FROM module "
. " ORDER BY mod_modulegrouporder ASC, mod_moduleorder ASC ";
If I can kindly say so, it sounds like you should do a SQL tutorial.

Display limit mysql php code

I don't understand how to display the first three rows (this number is an example limit) of a mysql database table with php code. I know how to use LIMIT, but in this case it seems not to work. Here is the code:
include("common.php");
$link=dbConnect();
$limit = safe($_POST['limit']);
$i = 1;
$query = mysql_query("SELECT * FROM $dbName . `scores` ORDER by `score` DESC LIMIT $limit");
while($row = mysql_fetch_array($query))
{
echo $i . "\t° \t " . $row['name'] . "\t - \t " . $row['score'] . "\n";
$i += 1;
}
This code produces an output like this: view image.
So it shows all the rows of the db table and not only the first three for example...
Thanks to everyone who will help me!
echo the text: "SELECT * FROM $dbName . scores ORDER by score DESC LIMIT $limit"
See what output it gives is the limit / dbName what you expect it to be
If you don't see what is wrong run the query in for example phpMyAdmin sql section see what errors you get in return.
Check two things $_POST['limit'] value and then $limit value. safe function may make it something different.

LIKE query is unable to retrieve data, why?

This query is unable to retrieve any data from MySQL for reasons I cannot figure out after countless hours..
public function search()
{
if(isset($_GET['search']))
{
$searchTerms = trim(strip_tags($_GET['search']));
$sth = $this->db->prepare("SELECT COUNT(*) FROM articles WHERE (article_content LIKE :search) OR (article_title LIKE :search)");
$sth->execute( array(':search' => '%' . $searchTerms . '%') );
if($sth->fetchColumn() > 0)
{
while($row = $sth->fetchAll(PDO::FETCH_ASSOC))
{
return "search results: " . $row['article_title'];
return "" . $row['article_content'];
}
} else {
echo "No results.";
}
}
}
No matter what keyword I type in the form it always returns "No results.". What could be the issue because from what I can see it should work..
Selecting all rows from the table structure and counting so that fetchColumn can be runned, it is selecting from the correct table (articles), where article_content and article_title are both rows in the table, so what is the issue?
$sth->execute(array(':search' => '%'.$searchTerms.'%'));
Should be:
$sth->execute(array(':search' => '\'%\' + \''.$searchTerms.'\' + \'%\''));
Each bind var needs to be an individual bind var, even when named, and even when they both contain the same value:
$sth = $this->db->prepare(
"SELECT COUNT(*)
FROM articles
WHERE (article_content LIKE :search1)
OR (article_title LIKE :search2)"
);
$sth->execute(
array(
':search1' => '%' . $searchTerms . '%',
':search2' => '%' . $searchTerms . '%'
)
);
Try this:
$sth = $this->db->prepare("SELECT COUNT(*) FROM articles WHERE (article_content LIKE :search0) OR (article_title LIKE :search1)");
$searchstring="%" . $searchTerms . "%";
$sth->execute( array(':search0' =>$searchstring ,':search1'=>$searchstring) );
pdo fails to retrieve values when the same placheholder is repeated in a query with LIKE in it.

PHP and mysqli: Select with multiple conditions using prepared statements

I'm working on some prepared statements using mysqli in a php file with a database running on InnoDB. Most of the statements are working pretty well, but I have a select statement with multiple conditions that keeps returning a syntax error in my select statement, to be specific: near ? AND section_num = ? AND dept = ? AND semester = ? AND year = ? at line 1 as well as the following error:
Call to a member function bind_param() on a non-object.
Here's the snippet of code:
if (!$rs = $mysqli->query("SELECT id FROM courses WHERE course_num = ? AND section_num = ? AND dept = ? AND semester = ? AND year = ?")) {
echo "Select Query Failed!: (" . $mysqli->errno . ") ". $mysqli->error;
}
if(!$rs->bind_param("ssssi", mysqli_real_escape_string($mysqli,$course_num), mysqli_real_escape_string($mysqli,$section_num),
mysqli_real_escape_string($mysqli,$dept), mysqli_real_escape_string($mysqli,$semester), mysqli_real_escape_string($mysqli,$year))) {
echo "Select Binding parameters failed: (" . $rs->errno .") " . $rs->error;
}
if (!$rs->execute()) {
echo "Execute select failed: (" . $rs->errno . ") " . $rs->error;
}
Any suggestions for how to form this statement to retrieve an id based on the 4 inputs would be great. Thanks!
You should be using prepare to prepare a statement, not query as that just executes a query.
$query = "
SELECT id
FROM courses
WHERE
course_num = ? AND section_num = ? AND dept = ? AND semester = ? AND year = ?
";
$rs = $mysqli->prepare($query);
$rs->bind_param("ssssi", $course_num, $section_num, $dept, $semester, $year);
$rs->execute();
Change: $mysqli->query("SELECT id ...
To: $mysqli->prepare("SELECT id ...
It is quite simple just do this
$query = "SELECT * FROM `$table_tran` WHERE `$mem_id` ='$member_id' and $status` = '$cur_status'";
$result = mysqli_query($link,$query);
It gets the data from the transaction table using the and statement.

PDO prepared statement not returning expected results

The prepared query returns the following resultset, when $this->show is set to saved-by-the-bell:
season
------
1
2
3
4
When I execute the following code:
$seasons = array( );
$query = $db->prepare(
"SELECT `season` " .
"FROM `tv` " .
"WHERE `show_url` = ':show' " .
"GROUP BY `season` " .
"ORDER BY `season` ASC;"
);
$query->bindParam( ':show', $this->show );
$query->execute( );
$query->setFetchMode( PDO::FETCH_OBJ );
while( $row = $query->fetch( ) )
{
$season = new stdClass;
$season->number = $row->season;
$season->title = "Season {$row->season}";
$season->url = $row->season;
$seasons[] = $season;
}
return $seasons;
$seasons is an empty array, why?
$db is an instantiated object that extends PDO.
I've tried all kinds of debugging methods, but when I echo the rowCount, it says 0. I'm still new to PDO, but I can't seem to see what's wrong here.
Thanks in advance.
Ahhh, I figured it out. I'll leave my stupidity up here, in case anyone else happens across this.
Apparently, when using prepared statements, you don't need to wrap your parameters in quotes in the SQL code.
So, the prepare statement should look like this:
$query = $db->prepare(
"SELECT `season` " .
"FROM `tv` " .
"WHERE `show_url` = :show " .
"GROUP BY `season` " .
"ORDER BY `season` ASC;"
);

Categories