I have other PDO Statements that execute fine, but this one is screwed up.
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->execute( array( 0, 10 ) );
The above does NOT work, but the below does work:
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT 0,10' );
$sth->execute( array( 0, 10 ) );
So why won't the first way display any of my results when it should be giving the same response?
So here is what I have now
$start = 0;
$perpage = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindValue(1, $start, PDO::PARAM_INT);
$sth->bindValue(2, $perpage, PDO::PARAM_INT);
$sth->execute();
this also does not work
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindParam(1, 0, PDO::PARAM_INT);
$sth->bindParam(2, 10, PDO::PARAM_INT);
$sth->execute();
The problem is likely that PDO will interpret any inputs as strings. You can try
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT :low,:high' );
$sth->bindValue(':low', 0, PDO::PARAM_INT);
$sth->bindValue(':high', 10, PDO::PARAM_INT);
$sth->execute();
Or
$low = 0;
$high = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT :low,:high' );
$sth->bindParam(':low', $low, PDO::PARAM_INT);
$sth->bindParam(':high', $high, PDO::PARAM_INT);
$sth->execute();
Source: How to apply bindValue method in LIMIT clause?
Not sure if you saw this question but have you tried casting the values you send as ints?
$start = 0;
$perpage = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindValue(1, (int)$start, PDO::PARAM_INT);
$sth->bindValue(2, (int)$perpage, PDO::PARAM_INT);
$sth->execute();
Or it says to do this:
$start = 0;
$perpage = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindValue(1, intval($start), PDO::PARAM_INT);
$sth->bindValue(2, intval($perpage), PDO::PARAM_INT);
$sth->execute();
This is because "prepare" and execute with array argument thinks your datas are string by default. So they escape them with ' '. THe problem is that when you deal with limits those quotes trigger error.
The solution is bindValue
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT :number OFFSET :start' );
$sth->bindValue("number",10, PDO::PARAM_INT);
$sth->bindValue("start",0,PDO::PARAM_INT);
$sth->execute();
What database? MySQL? SQL Server? Oracle?
In MySQL the PDO with LIMIT clause should work as in GlaciesofPacis's post. However, if you are using SQL SERVER you're not using the correct syntax. Referenced from StackOverflow question:
$query = "
DECLARE #Sort
SET ROWCOUNT :startRow
SELECT #Sort = SortColumn FROM Table ORDER BY SortColumn
SET ROWCOUNT :pageSize
SELECT ... FROM Table WHERE SortColumn >= #Sort ORDER BY SortColumn
";
$dbh->prepare($query);
$sth->bindParam(':startRow',0, PDO::PARAM_INT);
$sth->bindParam(':pageSize',10, PDO::PARAM_INT);
$sth->execute();
Related
Could someone please assist / advise on what I could do in order to make the last four search fields / inputs optional (along with AND statements) in the SQL query?
I have tried the code below but it doesn't seem to make the last four fields optional:
public static function findBySearch($location, $category, $type, $bedrooms, $bathrooms, $minamount, $maxamount)
{
$db = static::getDB();
$sql = 'SELECT * FROM posts
WHERE location = :location
AND category LIKE :category
AND type LIKE :type
AND
(:bedrooms IS NULL OR bedrooms = :bedrooms)
AND
(:bathrooms IS NULL OR bathrooms = :bathrooms)
AND
(:minamount IS NULL OR amount >= :minamount)
AND
(:maxamount IS NULL OR amount <= :maxamount)';
$stmt = $db->prepare($sql);
$stmt->bindValue(':location', $location, PDO::PARAM_STR);
$stmt->bindValue(':category', $category, PDO::PARAM_STR);
$stmt->bindValue(':type', $type, PDO::PARAM_STR);
$stmt->bindValue(':bedrooms', $bedrooms, PDO::PARAM_INT);
$stmt->bindValue(':bathrooms', $bathrooms, PDO::PARAM_INT);
$stmt->bindValue(':minamount', $minamount, PDO::PARAM_INT);
$stmt->bindValue(':maxamount', $maxamount, PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_CLASS, get_called_class());
return $result;
}
Is there a way i can do something like this:
$offset = "OFFSET $_POST['offset']";
$stmt = $db->prepare("SELECT * FROM table LIMIT 10 ? ");
$stmt->bindParam(1, $offset);
$stmt->execute();
If i put the variable directly in the query it works, but i need to bind it since users have access to that $_POST value, is there a better way of doing this?
OFFSET need to be in query not in variable
$offset = $_POST['offset'];
$stmt = $db->prepare("SELECT * FROM table LIMIT 10 OFFSET ?");
$stmt->bindParam(1, $offset, PDO::PARAM_INT);
$stmt->execute();
I'm making a function to query my database, fully, with a keyword search ($wordsToSearch) or with some category tags words($tagsToSearch) if there are.
This is my function, and it's not secure since i use the concat to add some part of the query. How should I use PDO to filter the variabiles and then add the part of the query when it is necessary?
Thanks to everybody
$wordsToSearch = " ";
$tagsToSearch = " ";
if(is_string($search)){
$wordsToSearch = "WHERE (
`artist_nm` LIKE '%".$search."%'
OR `place` LIKE '%".$search."%'
)";
}
if(is_string($searchtags)){
$arrayTags = explode(',', $searchtags);
$tagsToSearch = "HAVING (
`tags` LIKE '%".$arrayTags[0]."%' ";
foreach ($arrayTags as $key => $value) {
if($key != 0 && $key <= 20) {
$tagsToSearch .= "OR `tags` LIKE '%".$value."%' ";
}
}
$tagsToSearch .= ")";
}
$database->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$STH = $database->prepare('SELECT id, lat, lng, CONCAT_WS( "/&/", total, tags ) AS data
FROM (SELECT lat, lng, id, CONCAT_WS( "/&/", img_link, artist_nm, page_link, place, Total_Rating, Rating_Number ) AS total, GROUP_CONCAT( tag_name
SEPARATOR "," ) AS tags
FROM images
LEFT OUTER JOIN tbl_places ON images.id = tbl_places.KE_img
LEFT OUTER JOIN rel_tags ON images.id = rel_tags.Id_immagine
LEFT OUTER JOIN tags ON tags.Id_tag = rel_tags.Id_tag
'.$wordsToSearch.'
GROUP BY id '.$tagsToSearch.'
) AS subquery
');
try {
$STH->execute();
} catch(PDOException $e){
echo $e->getMessage();
die();
}
You are looking for prepared requests. You have to put compile your query with some parameters with prepare() method:
<?php
// With placeholders
$sth = $database->prepare('SELECT * FROM table WHERE id = ?');
// With named parameters
$sth = $database->prepare('SELECT * FROM table WHERE id = :id');
?>
Then you can execute the query using execute() method:
<?php
// With placeholders
$sth->bindParam(1, $yourId, PDO::PARAM_INT);
$sth->execute();
// or
$sth->execute(array($yourId));
// With named parameters
$sth->bindParam(':id', $yourId, PDO::PARAM_INT);
$sth->execute();
// or
$sth->execute(array(':id' => $yourId));
?>
Edit:
Of course you can put more than one parameter:
<?php
// With placeholders
$sth = $database->prepare('SELECT * FROM table WHERE username = ? AND password = ?');
$sth->bindParam(1, $username, PDO::PARAM_STR);
$sth->bindParam(2, $password, PDO::PARAM_STR);
$sth->execute();
// or
$sth->execute(array($username, $password));
// With named parameters
$sth = $database->prepare('SELECT * FROM table WHERE username = :username AND password = :password');
$sth->bindParam(':username', $username, PDO::PARAM_STR);
$sth->bindParam(':password', $password, PDO::PARAM_STR);
$sth->execute();
// or
$sth->execute(array(':username' => $username, ':password' => $password));
?>
More information in the documentation.
I am having a problem with binding param or value, does anybody knows what wrong?
If i change ? to area it works :-$
$item = 'area';
$query = dbConnectionPDO::getConnect()->prepare( ' SELECT * FROM ? ' );
$query->bindParam(1, $item, PDO::PARAM_STR);
$query->execute();
while($resultId = $query->fetch(PDO::FETCH_ASSOC)){
////
}
Is this a good solution? It works!
$select = 'select * from ' . $item . ' left join ' . $TableName . ' ';
$query = dbConnectionPDO::getConnect()->prepare("$select ON :three = :four");
$query->bindValue(':three', $three, PDO::PARAM_STR);
$query->bindValue(':four', $four, PDO::PARAM_STR);
$query->execute();
while($resultId = $query->fetch(PDO::FETCH_ASSOC)){
////
}
You're trying to bind a table name, not a parameter. I'm not sure you can actually do that.
bindParam works by binding question-mark holders or named parmeters, not a table name.
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$sth->bindParam(1, $calories, PDO::PARAM_INT);
$sth->bindParam(2, $colour, PDO::PARAM_STR, 12);
$sth->execute();
If you're just looking into placeholder "replacement" you can just use sprintf, but be careful since if you'll be doing anything fishy or stupid (like accepting the table name from an external source), it might be leaky.
For example:
$theQ = "SELECT * FROM `%s` LEFT JOIN `%s` ON `%s` = `%s`";
$runQ = sprintf($theQ, 'one', 'two', 'three', 'four');
You need to provide a valid SQL statement where only literals are parametrized. Even if the database driver is dumb enough to accept the query, you'll end up executing something like:
SELECT * FROM 'area'
... which is obviously not what you intended.
You cant parametrize a table name, only parameters.
How can I run multiple select statements in the same query in PDO? My SQL statement works fine when I run it in phpMyAdmin? Code is below:
$sql = 'SELECT DISTINCT apartment.apartmentName,
apartment.apartmentID
FROM apartment_information apartment,
apartment_ratings ratings,
apartment_floorplans floorplan,
user_user user
WHERE user.preferred_zip = :zip
AND floorplan.apartmentID = apartment.apartmentID
AND floorplan.apartmentID = (SELECT apartmentID
FROM apartment_floorplans
WHERE monthlyPrice < :monthlyPrice
AND apartmentNumBedrooms = :apartmentNumBedrooms
AND apartmentNumBathrooms = :apartmentNumBathrooms)';
try{
echo $sql;
$stmt = $this->_db->prepare($sql);
$stmt->bindParam(":zip", $this->_zip, PDO::PARAM_STR);
$stmt->bindParam(":monthlyPrice", $this->_apartmentFloorPlans['Price'], PDO::PARAM_STR);
$stmt->bindParam(":apartmentNumBedrooms", $this->_apartmentFloorPlans['Bedrooms'], PDO::PARAM_STR);
$stmt->bindParam(":apartmentNumBathrooms", $this->_apartmentFloorPlans['Bathrooms'], PDO::PARAM_STR);
}
$stmt->execute();