This question already has an answer here:
Can I use a PDO prepared statement to bind an identifier (a table or field name) or a syntax keyword?
(1 answer)
Closed 3 years ago.
Is it possible pass a column name as parameter in a prepared MySQL statement? Take the following example:
UPDATE Images
SET :placement = :imageURL
WHERE ID = :titleID;
PDO adds ' around each parameter, so the middle line above becomes:
SET 'Homepage' = '1.jpg'
Which MySQL doesn't like. Is there a way to include parameters for fieldnames in PDO statements and have them accepted?
Otherwise I guess I'll have to write several different PDO statements, depending on what's been chosen(?).
You would need to do something like this:
$column = 'someColumn';
$stmt = $db->prepare("UPDATE tableName SET {$column} = :columnValue WHERE ID = :recordId");
Parameterized placeholders are only for values.
I would suggest you read the comment #YourCommonSense posted on your question.
In situations such as this, I use a different sort of replacement parameters, like so:
$unitLabel = 'store_number';
$sql = 'select * from users where [unitLabel] = :unit and level = :level;';
$sql = str_replace('[unitLabel]', $unitLabel, $sql);
$params = array(
':unit' => 300,
':level' => 'admin',
);
$stmt = $dbh->prepare($sql);
$stmt->execute($params);
The prepared SQL query ends up being processed (more or less) as:
SELECT * FROM USERS WHERE store_number = 300 AND level = 'admin';
Which works for my situation. I hope this helps. :)
Related
This question already has answers here:
Use an array in a mysqli prepared statement: `WHERE .. IN(..)` query [duplicate]
(8 answers)
How can I bind an array of strings with a mysqli prepared statement?
(7 answers)
Closed 11 months ago.
If I have this array:
$ids = [1, 34, 36];
How do I get data from a table from each of ID using this query:
$query = $DB->Prepare('SELECT name, address FROM tContacts WHERE id = ?');
I tried using:
foreach ($ids AS $val) {
$query = $DB->Prepare('SELECT name, address FROM tContacts WHERE id = ?');
$rs = $DB->Execute($query, array($val));
$i = 0;
foreach($rs as $rows)
{
$rs[$i++]=array(
'name' => $rows['name'],
'address' => $rows['address']
);
}
}
And when I tried to:
print_r($rs);
It only display the last row, not 3 rows as I intended.
You should use the IN function in the SQL condition.
Combine it with a php function to repeat the placeholders N times where N is the amount of the requested IDs in the array.
$ids = array(1,434,23);
$query = "SELECT name, address FROM tContacts WHERE id IN('".join("','",$ids)."')";
$stmt = $DB->Prepare($query);
Originally i've used str_repeat, but #pokeybit came up with an idea to use join which is much more comfortable.
In case the $ids array is being built based on a user's input or so, it would be better to use the query prepare mechanism and use placeholders.
$count = count($ids);
$query = "SELECT name, address FROM tContacts WHERE id IN(".str_repeat('?,',$count-1)."?)"; //would output: IN(?,?,?)
Then, use a loop to bind the relevant IDs from the array.
Note 1: Both of the ideas work, one is in case the developer sets the array, the other one use the advantages of preparing queries and binding which is a better solution in case the array's in dynamic/input-based. Therefore, I've wrote both of the solutions.
Note 2: See #JaredFarrish last comment regarding the advantages of prepared queries.
This question already has answers here:
pdo prepared statements with wildcards
(2 answers)
Closed 5 years ago.
I'm trying to query posts using PDO where the database column 'tags' = something.
My problem is: I want my query to work even if there's no $_GET['tag'] request is set and here's my code.
if (!isset($_GET['tag'])) {
$tags = '%';
} else {
$tags = $_GET['tag'];
}
$get_recipes = $con->prepare ("SELECT * FROM recipes WHERE tags = ?");
$get_recipes->execute(array($tags));
$recipes = $get_recipes->fetchAll();
Is it valid to set the PHP variable $tags to the MySQL wildcard %? if not possible then what should I do to make my query work?
When I run that code and there's not $_GET['tag'] is written the query will not fetch any posts from the database.
Using Wildcards in Prepared Statements With PDO
When using a wildcard in MySQL you must use the LIKE operator. It is correct to bind the wildcard with parameters in PDO.
You would prepare your statement like so.
$get_recipes = $con->prepare ("SELECT * FROM recipes WHERE tags LIKE ?");
And then you would bind your parameter using the % character, like so.
$get_recipes->execute(array('%'));
While that is the correct way to use a wildcard in the way you've proposed, that is not the correct solution to do what you're trying to do.
How to achieve what you're trying to achieve
In your code it looks like you want to select all rows if $_POST['tags'] is not set, and if it is set you want to select all rows that have the tags column set to the value of $_POST['tags']. To do this, you would want to prepare your statement inside the conditional, like so.
if (!isset($_GET['tag'])) {
$get_recipes = $con->prepare ("SELECT * FROM recipes");
$get_recipes->execute();
} else {
$get_recipes = $con->prepare ("SELECT * FROM recipes WHERE tags = ?");
$get_recipes->execute(array($_GET['tag']));
}
$recipes = $get_recipes->fetchAll();
This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 2 years ago.
I'm making a game using PHP with MySQL and I need an UPDATE query where the fields names could change from one user to another.
My code is:
$upd = $sql->prepare("UPDATE empire_users SET :p = :p + :p2 WHERE id = :id");
$upd->execute(array(
':p' => "p".$type,
':p2' => 10,
':id' => $_SESSION["id"]
));
In my database, users have 3 columns : pwood, pstone, pwheat, and $type could only be "wheat", "stone", or "wood".
I want to update the selected field (which depends of $type) to increase by p2 (here 10).
See http://php.net/manual/fr/pdo.prepare.php, especially following comment:
"To those wondering why adding quotes to around a placeholder is wrong, and why you can't use placeholders for table or column names:
There is a common misconception about how the placeholders in prepared statements work: they are not simply substituted in as (escaped) strings, and the resulting SQL executed. Instead, a DBMS asked to "prepare" a statement comes up with a complete query plan for how it would execute that query, including which tables and indexes it would use, which will be the same regardless of how you fill in the placeholders.
The plan for "SELECT name FROM my_table WHERE id = :value" will be the same whatever you substitute for ":value", but the seemingly similar "SELECT name FROM :table WHERE id = :value" cannot be planned, because the DBMS has no idea what table you're actually going to select from."
Thanks for your answers, I corrected :
$upd = $sql->prepare("UPDATE empire_users SET p".$type." = p".$type." + :p2 WHERE id = :id");
$upd->execute(array(
':p2' => 10,
':id' => $_SESSION["id"]
));
This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 9 years ago.
I want to fetch results from a MySQL database with PDO. The user should be able to order them by tablerow by which type (ascending or descending). This seems to only work when you hardcode it.
Does work:
$query = "SELECT * FROM ".$config->dbPrefix."content
WHERE cat_id = 2
ORDER BY id DESC
";
$query = $pdo->prepare($query);
$query->execute();
$result = $query->fetchAll();
Doesn't work:
$orderRow = 'id'; //from $_POST
$orderType = 'DESC' //from $_POST
$query = "SELECT * FROM ".$config->dbPrefix."content
WHERE cat_id = 2
ORDER BY :orderRow :orderType
";
$query = $pdo->prepare($query);
$query->bindValue(':orderRow', $orderRow);
$query->bindValue(':orderType', $orderType);
$query->execute();
$result = $query->fetchAll();
So my question is: what is the best way to do this and why isn't this implemented?
The best way I can think of is using a switch statement and writing the query for every different option which would have like 14 different available cases.
You can only provide placeholders for values in an SQL statement, not for column names or other kind of identifiers.
So instead of using bindValue, put the values in like you do for #config->dbPrefix, directly into the string. Make sure however that no SQL injection is possible.
I want to create prepared stmt such as
"SELECT id,latitude,longitude
FROM sometable WHERE
(3437.74677 * ACOS(SIN(latitude_radians) * SIN(?) +
COS(latitude_radians)*COS(?) * COS(longitude_radians - ?))) <= ?";
in PHP. Where clause is a function of column values and bind variables
but how should I bind the values. Or is this even a legal prepared stmt?
Thanks in advance,
-v-
I don't see any problem here.
See:
PHP Prepared Statements.
Extremely minimal sample:
$stmt = $dbh->prepare( $QUERY );
$stmt->execute( $arguments_array )
Sorry for being unclear.
As I understand following is an example of PHP prepared stmt,
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
if ($stmt->execute(array($_GET['name'])))
Now the where clause is always a simple, column = ? AND column2 = ?. In my case though its function and it didnt work when assigned values to the bind variables. I will regenerate the error again and post it.
I was wondering then if it is even legal to have a function of column names and bind variables in the where clause.