I am trying to retrieve one result from my database table 'members' using a prepared call.
$favid = 1;
$type = "favdeal";
$action = 1;
$user_id = 1;
$stmt = $mysqli->prepare("SELECT ? FROM members WHERE id=?");
$stmt->bind_param('ss', $type, $user_id);
$stmt->execute();
$stmt->bind_result($favs);
while ($stmt->fetch()) {
print($favs);
}
$stmt->close();
This is the only way i managed to get any kind of result.
The table has a column called 'favdeal' which has a value of '2' in it.
The result printed returns the name of the column not the value.
So my question is how do i get the value '2' instead of the name of the column?
You can't bind columns (or tables) from doing a SELECT as you have in SELECT ?.
Select an actual column.
Or, if you want to do it dynamically, you need to use a variable.
Example: SELECT $type <= that is allowed.
However, column names can be binded when using a WHERE clause.
Example: SELECT column FROM table WHERE column=?
which you are presently using => WHERE id=?
Consult the manual on bind_param()
http://www.php.net/manual/en/mysqli-stmt.bind-param.php
Footnotes:
If you happen to use an MySQL reserved word (it could happen), you will need to wrap your column's variable with backticks.
For example: (if using $type="from";) "from" being a reserved word.
SELECT `$type` FROM members WHERE id=?
For a list of MySQL reserved words, visit the following page:
http://dev.mysql.com/doc/refman/5.5/en/reserved-words.html
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 have a variable, $ids
It is a , separated string so it can be $ids = "1" or $ids = "1, 3, 7, 8"
What i want to do is update the database based on these values so i have :
$query = "UPDATE Fields SET Value = '1' WHERE Id IN '$ids'";
And also:
$query = "UPDATE Fields SET Value = '1' WHERE Id '$ids'";
What is the best way to update the database, should i split the string in to an array, and then do a for each loop? or is there a better way?
Save the fact that it's wide open to SQL Injection, this line works for one or many id's:
$query = "UPDATE Fields SET Value = '1' WHERE Id IN ($ids)";
Now, to keep yourself from SQL Injection attacks, which is obviously up to you, you'd want to explode that array and send multiple update statements like this:
$query = "UPDATE Fields SET Value = '1' WHERE Id = :Id";
There's nothing inherently wrong with using an IN clause here. Any WHERE clause works for an UPDATE statement. You'll just want to treat the numbers as a list of values instead of a string. Something like this:
$query = "UPDATE Fields SET Value = '1' WHERE Id IN ($ids)";
The really important part is how you get the $ids value into the query in the first place. You don't show that in the question, but you'll want to make sure you're not opening yourself to a SQL injection vulnerability. Make sure you're properly sanitizing inputs and using prepared statements. How prepared statements handle lists of values vs. individual values is up to the data access technology being used.
Use this query:
$query = "UPDATE Fields SET Value = '1' WHERE Id IN ($ids)";
Where $ids should be formatted als 1,2,3,4. Don't forget to check them before execution (SQL Injection).
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. :)
This question already has an answer here:
Bind multiple parameters into mysqli query
(1 answer)
Closed 5 years ago.
I need to make a simple query
$array_of_ids = array();
//poulate $array_of_ids, they don't come from another db but from Facebook
//so i can't use a subquery for the IN clause
$wpdb->prepare("SELECT id from table where id IN (%d, %d)", $array_of_ids [0], $array_of_ids [1]);
The question is, if i have 200 elements in the array, what is the correct way to handle this?Do i have to manually build the query with 200 %d? I need this query because i must "sync" my database with facebook data and i have to check if the user i have in the db are present, update those that are present, insert new users and delete those that are not my friend.
If you know for certain that the array elements are numeric:
$wpdb->prepare("SELECT id FROM table WHERE id IN ("
. implode(',',$array_of_ids) . ")");
Otherwise, you can use the vsprintf form of prepare to pass in the array of parameters:
$wpdb->prepare("SELECT id FROM table WHERE id IN ("
. str_repeat("%d,", count($array_of_ids)-1) . "%d)" , $array_of_ids);
I'm not sure that this is a good approach, but you could do it in this fashion:
$sql = "SELECT id from table where id IN ("
. implode(',', array_fill(0, count($array_of_ids), "%d"))
. ")";
call_user_func_array(array($wpdb, 'prepare'), $array_of_ids);
This builds a string with the appropriate number of %d, then uses call_user_func_array to do it dynamically.
That said, I'm not sure this is really a case where prepared statements are worth the hassle, given how easy it is to sanitise integers.
Yes, dynamic sql is the way here. Fortunately, integers are easy to not screw up with.
$vals = array_filter(array_map('intval', $vals));
make sure you have at least one value and then implode it. Not need for a prepared statement here, just execute the sql.
Since this has no accepted answer yet I'll go with my approach with array_filter
$array_of_ids = array(0,1,1,2,3,5,8,13);
echo "SELECT id from table where id IN (".implode(',', array_filter($array_of_ids,'is_int')).")";
will output
SELECT id from table where id IN (0,1,1,2,3,5,8,13)
while
$array_of_ids = array('zero',1,true,2,3,5,8,'thirteen');
echo "SELECT id from table where id IN (".implode(',', array_filter($array_of_ids,'is_int')).")";
will output
SELECT id from table where id IN (1,2,3,5,8)
Please note that is_int doesn't work with $_GET variables so use is_numeric instead
You can do this :
$query = $wpdb->prepare("SELECT id from table where id IN :param");
$query->bindParam("param", "(".implode(',', array_map('intval', $array_of_ids)).")");