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();
Related
I've got a simple query that is not so easy to execute in PHP script:
SELECT `title` from `MY_TABLE` WHERE id in (30,32,33,44)
Usually I execute sql queries with prepared statements. I place a bunch of ? and than bind parameters. This time the numbers in parenthesis are an array of data I get from the user.
I tried this, but it does not work:
$ids = [30,32,33,44];
$stmt = $mysqli->prepare("
SELECT `title` from `MY_TABLE` WHERE id in (?)
");
// $stmt->bind_param();
$stmt->bind_param("i",$ids);
$stmt->execute();
$stmt->bind_result($title);
$stmt->store_result();
//fetch
How can I execute a set operation with prepared statements?
UPDATE:
After following your advice I came up with this
$ids = [30,32,33,44];
$questionMarks = rtrim(str_repeat('?,',count($ids)),", ");
$parameters = str_repeat('i',count($ids));
echo $questionMarks."<br>";
echo $parameters."<br>";
$stmt = $mysqli->prepare("
SELECT `title` from `MY_TABLE` WHERE id in (".$questionMarks.")
");
$scene_names = [];
$stmt->bind_param($parameters, $ids); //error here
$stmt->execute();
$stmt->bind_result($title);
$stmt->store_result();
I am still getting an error. This time it says:
Number of elements in type definition string doesn't match number of bind variables
I am not sure why it thinks that the number of elements (what is element in this case?) is wrong.
UPDATE 2:
Instead of:
$stmt->bind_param($parameters, $ids); //error here
I used:
$stmt->bind_param($parameters, ...$ids); //error gone
Taraam. Works fine.
Something like:
$ids = [30,32,33,44];
$types = array();
foreach($ids as $i){
array_push($types,'i');
}
$params = array_merge($ids,$types);
$sqlIN = str_repeat('?,',count($ids));
$sqlIN = rtrim($sqlIN, ',');
//Value of $sqlIN now looks like ?,?,?,?
$sql = "SELECT title from MY_TABLE WHERE id IN ($sqlIN)";
$stmt = $mysqli->prepare($sql);
call_user_func_array(array($stmt, 'bind_param'), $params);
$stmt->execute();
$stmt->bind_result($id);
$stmt->store_result();
First, according to another SO post, I tried combining the two statements into one.
<?php
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
$sql = "UPDATE users SET pass = :password WHERE usrn = :id;
SELECT prim FROM users WHERE usrn = :id;";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->bindParam(":password", password_hash($_POST["password"], PASSWORD_DEFAULT));
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC); //// line 71
?>
However, this kept throwing the error: Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error on line 71.
I couldn't find any relevant solutions to this issue, so I decided to simply split up the two statements.
<?php
$sql = "UPDATE users SET pass = :password WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->bindParam(":password", password_hash($_POST["password"], PASSWORD_DEFAULT));
$stmt->execute();
$sql = "SELECT prim FROM users WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION["session"] = $result["prim"];
?>
But a var_dump($result) is returning Bool(false), so obviously something is not working right with fetching the result and storing it as a variable, it seems, in both cases.
I'm new to PHP and MySQL, so I'm at a loss right now.
Change this,
$sql = "SELECT prim FROM users WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION["session"] = $result["prim"];
To this,
$sql = "SELECT prim FROM users WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->execute(); // Your problem
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION["session"] = $result["prim"];
You are missing the execution of the query.
My sql, keeps on producing an error with an empty result. I'm trying to select a past student from the database that has got the same grades and results as a past student stored in the database. I'm using pdo statements to prepare the statements.
I keep on getting returned empty queries, even though in the database there is a student that has taken maths (subject 1) and got an A (grade1). This query won't work.
$query = $db->prepare("SELECT * FROM paststudent WHERE subject1 = :subject1 AND grade1 = :grade1");
.
if ($autumn != "" and $winter == "" and $spring == "" and $summer == "") {
$query = $db->prepare("SELECT * FROM paststudent WHERE subject1 = :subject1 AND grade1 = :grade1 AND subject2 = :subject2 AND grade2 = :grade2 AND subject3 = :subject3 AND grade3 = :grade3 AND subject4 = :subject4 AND grade4 = :grade4 AND autumn = :autumn");
// binds the value to the query variable
$query->bindValue(':subject1', $subject1, PDO::PARAM_STR);
$query->bindValue(':grade1', $grade1, PDO::PARAM_STR);
$query->bindValue(':subject2', $subject2, PDO::PARAM_STR);
$query->bindValue(':grade2', $grade2, PDO::PARAM_STR);
$query->bindValue(':subject3', $subject3, PDO::PARAM_STR);
$query->bindValue(':grade3', $grade3, PDO::PARAM_STR);
$query->bindValue(':subject4', $subject4, PDO::PARAM_STR);
$query->bindValue(':grade4', $grade4, PDO::PARAM_STR);
$query->bindValue(':autumn', $autumn, PDO::PARAM_STR);
// executes the query
$query->execute();
// the value of the query is stored to result
$result = $query->fetch(PDO::FETCH_ASSOC);
// fetch() instead of fetchAll just gets the first result
}
can you please dump your sql query here, that will be easy to solve your problem. what i can see that all the AND condition and if any of AND condition false then you will get empty result.
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 have two stored procedures in my database Postgres, both have the same name but the difference are the parameters.
procedure1(::string, ::integer, ::string, ::integer)
procedure1(::string, ::integer, ::integer)
In PDO doing bindParam correct, is coming STR, INT, INT but the prepere always performs procedure1.
How do I get him to understand what I call the procedure2?
Some information for more help? I clear? thanks
EDIT ===
...
$bounds = null; // forced for debug
if(!is_null($bounds)){
$query = "SELECT procedure1(:name, :domain, :geo, :userid)";
$stmt = $db->prepare($query);
$stmt->bindParam('name', $name, PDO::PARAM_STR);
$stmt->bindParam('domain', $idDomain, PDO::PARAM_INT);
$stmt->bindParam('geo', $geoString, PDO::PARAM_STR);
$stmt->bindParam('userid', $userId, PDO::PARAM_INT);
}else{
$query = "SELECT procedure1(:name, :domain, :userid)";
$stmt = $db->prepare($query);
$stmt->bindParam('name', $name, PDO::PARAM_STR);
$stmt->bindParam('domain', $idDomain, PDO::PARAM_INT);
$stmt->bindParam('userid', $userId, PDO::PARAM_INT);
}
$result = $stmt->execute();
...
The error it gives is that he is running a procedure that requires four parameters
Try changing your $query statements to explicitly tell PDO the types, and to avoid extra code switch to bindValue (PDO uses the PARAM flags to format SQL, not to cast data types):
$bounds = null; // forced for debug
if(!is_null($bounds)){
$query = "SELECT procedure1(:name::VARCHAR, :domain::INTEGER, :geo::VARCHAR, :userid::INTEGER)";
$stmt = $db->prepare($query);
$stmt->bindValue('name', $name);
$stmt->bindValue('domain', $idDomain);
$stmt->bindValue('geo', $geoString);
$stmt->bindValue('userid', $userId);
}else{
$query = "SELECT procedure1(:name::VARCHAR, :domain::INTEGER, :userid::INTEGER)";
$stmt = $db->prepare($query);
$stmt->bindValue('name', $name);
$stmt->bindValue('domain', $idDomain);
$stmt->bindValue('userid', $userId);
}
$result = $stmt->execute();