programming WHERE section in sql - php

Example i'm getting 2 variable from my db.($v1, $v2)
SELECT * FROM mytable WHERE id=$1 AND $v2
But in another example im getting 3 variable from db ($v1, $v2, $v3)at same query cause i proggramed it like it. In this condition how can i program WHERE statement of sql query
edit
WHERE id=$v1 AND $v2 AND $v3 // i want to add it And conditions automaticly

If you need to find any records which contain any of your variable you can use OR as follow
SELECT * FROM mytable WHERE id = $v1 OR id = $v2 OR id = $v3

If you are trying to select multiple ID values, use IN conditional:
SELECT * FROM mytable WHERE id IN ($v1, $v2, $v3)
EDIT: Asked for a flexible way to add values:
Assuming that this query is set by a function and this function will receive all ID values that should be in where clause. Something like:
<?php
$example_ids = array(1, 5, 7, 15, 22);
wherein($example_ids)
function wherein($ids){
// Select part
$query = "SELECT * FROM mytable ";
// Where statement
$where = " WHERE id IN (";
// For loop to use each value sent
// as a value in IN (...
for ($i=0; $i < count($ids); $i++) {
// Eg: $i = 0
// $ids[$i] = 1
//
// So:
// WHERE id IN (1
$where .= $ids[$i];
// If its not the last value then
// add a comma for SQL syntax
if ($i < count($ids) - 1)
/// Where id IN (1,
$where .= ",";
}
// At the end of the loop, $where must be
// something like:
// WHERE id IN (1,5,7,15,22
//
// Once again, for SQL syntax, the close )
$where .= ")";
// Finaly, the last step, putting all together:
// SELECT * FROM mytable WHERE id IN (1,5,7,15,22)
$query .= $where;
}

Related

How to enter variable into prepared stmt that will retrieve all from the column?

I'm making a search filter on my events website. There are 3 drop down inputs: Location, event type, date.
When the user submits the search filter, the form posts values that changes the mysql query which will display different events on the user screen. I'm having trouble finding a flexible solution.
Right now my query is like this:
$filter = $database->prepared_query("SELECT * FROM onlineevent WHERE event_location = (?) AND event_type = (?) AND event_date = (?)", array($l, $t, $d));
How can I make $l retrieve ALL possible values for event_location? The same goes for $t and $d. I thought I could set $l to '*' but that doesn't work.
The problem now is if the user doesn't select a value for $l, and they do select a value for $t and $d, then the query doesn't work. I want to set the default value for each variable to bring all results for each condition.
So if the user doesn't select any filter and submits the form, the query I'm looking for would look something like this:
$filter = $database->prepared_query("SELECT * FROM onlineevent WHERE event_location = (?) AND event_type = (?) AND event_date = (?)", array(ALL, ALL, ALL));
The original version of Ali_k's answer was almost right, but made the mistake of including the whole clause as a parameter, rather than just the value. That would cause the whole clause to be seen as a string value, rather than as code with values within it.
The idea of building up the string gradually - and, crucially, only adding a clause if there's actually value specified in the search parameters - is correct though. You also need need to build up the parameter array separately at the same rate.
Here's a version which should actually execute correctly:
$sql = "SELECT * FROM onlineevent";
$sqlfilters = "";
$parameters = array();
if( !empty($l) ){
$sqlfilters .= " event_location = ?";
$parameters[] = $l;
}
if( !empty($t) ){
$sqlfilters .= ($sqlfilters != "" ? " AND" : "")." event_type = ?";
$parameters[] = $t;
}
if( !empty($d) ){
$sqlfilters .= ($sqlfilters != "" ? " AND" : "")." event_date = ?";
$parameters[] = $d;
}
if ($sqlfilters != "") sqlfilters = "WHERE ".$sqlfilters; //add a WHERE clause if needed
$sql .= $sqlfilters; //add the filters to the initial SQL
$filter = $database->prepared_query($sql, $parameters);
Maybe I'm misunderstanding you but aren't you just looking for:
$filter = $database->prepared_query("SELECT * FROM onlineevent")
OR
$filter = $database->prepared_query("SELECT * FROM onlineevent WHERE event_location IS NOT NULL AND event_type IS NOT NULL AND event_date IS NOT NULL")
Your question is not quite clear and it is also not clear how the prepare function works, but here is my suggestion:
$array = array();
$query_parms = '';
if( !empty($l) ){
$array[] = $l;
$query_parms .= 'event_location = (?)';
}
if( !empty($t) ){
$array[] = $t;
$query_parms .= count($array) > 1 ? 'AND event_type = (?)' : 'event_type = (?)';
}
if( !empty($d) ){
$array[] = $d;
$query_parms .= count($array) > 1 ? 'AND event_date = (?)' : 'event_date = (?)';
}
$filter = $database->prepared_query("SELECT * FROM onlineevent WHERE " . $query_parms, $array);

Bind parameters with PDO in PHP

I am using PDO in php. But when my query have any keyword like " ' " means hyphen it breaks and through an error.
I ready through on internet and find solution to bind parameters with query and it works fine.
But the issue is i am building the query in loop and i am not able to bind parameters within loop.
Here is code in which i am splitting the array with space and run query on every keyword.
The first 3 words will have only like query and more then 3 words i am using loop to concatenate the all array elements and same with more then 6 words i am using MATCH query.
Is there any way to escape that hyphen or how can we bind parameters using loop in my case?
$keyword = ($_POST['keyword']);
$keyword_array = split(' ',$keyword);
/* Query For first Three Words */
if(count($keyword_array)<=3){
$sql = "SELECT * FROM faq WHERE question LIKE '%$keyword%' limit 14";
}
/* Query through all array when words are greater then 3 */
if(count($keyword_array)< 6){
$sql = "SELECT * FROM faq WHERE question ";
for($i = 0 ; $i<count($keyword_array); $i++){
if($i==0){
$sql.=" LIKE '%$keyword_array[$i]%'";
}else{
$sql.=" or question LIKE '%$keyword_array[$i]%' ";
}
}
$sql .= " ORDER BY question ASC LIMIT 0, 8";
}
/* Appl FULL TEXT in natual language mode once we have enough phrase */
else if(count($keyword_array)>=6){
$sql = "SELECT * FROM faq WHERE ";
for($i = 0 ; $i<count($keyword_array); $i++){
if($i==0){
$sql.=" MATCH (answer) AGAINST ('$keyword_array[$i]' in natural language mode) ";
}else{
$sql.=" or MATCH(answer) AGAINST('$keyword_array[$i]' in natural language mode) ";
}
}
$sql .= " limit 0,5";
}
$execute_faq_query = $conn->query($sql);
$execute_faq_query->setFetchMode(PDO::FETCH_ASSOC);
while ($list = $execute_faq_query->fetch()){
}
When building a dynamic query you need to separate those parts of the query that are static from those that are dynamic.
You can see that the following code is static.
"SELECT * FROM faq ";
The rest of the code is dynamic. When filtering records the WHERE clause is used and the AND & OR operators are used to filter records based on more than one condition. The AND operator displays a record if both the first condition AND the second condition are true. The OR operator displays a record if either the first condition OR the second condition is true. so for the first condition WHERE is used but after that AND or OR must be used(using OR in your example)
// Static code
sql = "SELECT * FROM `faq`"
// Set initial condition to WHERE
clause = "WHERE";
if( !empty( filter )){
Add clause to sql
Add condition to sql
change clause to OR or AND as required
}
Repeat for each filter
Note the filter is not changed until a filter is applied and remains changed once changed.
The remaining static code, if any,is added after all the filters have been handled.
I have used Switch Case to apply filters and unnamed parameters ?.
Use "lazy" binding when possible - passing data into execute will dramatically shorten your code. See PDO info.
//Test $POST[] remove after testing
$_POST['keyword'] ="one two three four five six";
$keyword = ($_POST['keyword']);
$keyword_array = split(' ',$keyword);
$words = count($keyword_array);
echo $words;
//You need an array to store parameters
$paramArray =array();
//Initial clause
$clause = "WHERE";
//Start with a basic stub
$sql = "SELECT * FROM faq ";
switch (true) {
case $words <= 3:
$sql .= " $clause question LIKE ?";
$keyword = "%$keyword%";
array_push($paramArray,$keyword);
$limit = " LIMIT 14";
break;
case $words < 6:
for($i = 0 ; $i<count($keyword_array); $i++){
$sql .= " $clause question LIKE ?";
$keyword = "%$keyword_array[$i]%";
array_push($paramArray,$keyword);
$clause = "OR";
$limit = " ORDER BY question ASC LIMIT 0, 8";
}
break;
case $words >=6:
$clause = "";
for($i = 0 ; $i<count($keyword_array); $i++){
$sql.=" $clause MATCH (answer) AGAINST (? in natural language mode) ";
array_push($paramArray,$keyword_array[$i]);
$clause = "OR";
$limit = " limit 0,5";
}
break;
}
//echo query and parameter array remove after testing
echo $sql;
echo "<br>";
print_r($paramArray);
//Prepare and execute query
$execute_faq_query = $conn->prepare($sql);
$execute_faq_query->execute($paramArray);
$execute_faq_query->setFetchMode(PDO::FETCH_ASSOC);
while ($list = $execute_faq_query->fetch()){
}

I'm trying to perform calculations based on user selection values

I'm trying to create a query in php that retrieves values from a database and multiplies them with user input. The user selects an item enters a number and I want the query to multiply the number with different values depending on the item that the user selected. For example, when the user selects an item from id 1 and enters a number, I want the query to retrieve values from id 1 multiply it with the number and if the user selects id 2, the number should be multiplied with values from id 2. Here's what I have so far.
$value = isset($_POST['selection']);
switch ($value){
case 1 :
$strSQL = "SELECT * FROM table1 WHERE id ='1' ";
$rs = mysql_query($strSQL);
while ($row = mysql_fetch_array($rs)) {
$q1 = $row['Rate_1' ];
$q2 = $row['Rate_2'];
}
$c1 = $input * $q1 ;
$c2 = $input * $q2 ;
$total = $c1 + $c2;
echo $total;
break; }
case 2 :
$strSQL = "SELECT * FROM table1 WHERE id ='2' ";
$rs = mysql_query($strSQL);
while ($row = mysql_fetch_array($rs)) {
$q1 = $row['Rate_1' ];
$q2 = $row['Rate_2'];
}
$c1 = $input * $q1 ;
$c2 = $input * $q2 ;
$total = $c1 + $c2;
echo $total;
break;
}
I have a form where the user enters a number but when I click calculate, it doesn't bring up any results.
You are closing your switch before it ends, https://eval.in/418432. Error reporting would have shown this. Aside from this you are running the same code twice. Might as well use the value in the query (note we cast the value as int, never pass user input direct to a query, this opens you to SQL injections, another approach with this driver is, http://php.net/manual/en/function.mysql-real-escape-string.php).
if(isset($_POST['selection']) && ($_POST['selection'] == 1 || $_POST['selection'] == 2)){
$id = (int)$_POST['selection'];
$strSQL = "SELECT * FROM table1 WHERE id = $id";
$rs = mysql_query($strSQL);
$row = mysql_fetch_array($rs); // id is auto-incrementing presumably so no need to loop, only 1 row
$q1 = $row['Rate_1' ];
$q2 = $row['Rate_2'];
$c1 = $input * $q1 ; //dont know where $input is defined but presuming you took care of that else where in the code
$c2 = $input * $q2 ;
$total = $c1 + $c2;
echo $total;
} else {
echo 'Invalid value passed in';// or do nothing here and take out the else.
}
It would also be best to update your db driver to mysqli or pdo which will allow you to use prepared statements.
Here's a thread on getting error messages,
How to get useful error messages in PHP?
and a thread on SQL injection prevention,
How can I prevent SQL injection in PHP?

Query Multiple Conditions

I am keeping track of a few things on my site and im using a lot of queries because they need different conidtions
for example
$example = mysql_query("SELECT column FROM table WHERE column = 'Value1'");
$example_row = mysql_num_rows($example);
$example1 = mysql_query("SELECT column FROM table WHERE column = 'Value2'");
$example_row1 = mysql_num_rows($example1);
And so on, the value is always different so im having trouble finding a way to make this in to one query where i could still get different rows count for different values, is it possible?
I could test the row to see if it matches the value
if ($row == 'value'){
}
Multiple times but it still seems bad
Use IN()
SELECT column FROM table WHERE column IN('Value1', 'Value2');
I believe you want the count per value:
$values = ["value1", "value2", ...];
$query = "SELECT ";
for($i = 0; $i < count($values); $i++)
{
$query .= "SUM(IF(column = '$values[$i]')) AS v$i";
if($i != count($values) - 1)
$query .= ","; //Only add ',' if it's not the last value
$query .= " "; //We need the spaces at the end of every line
}
$query .= "FROM table";
//Let mysql do its work, run the query etc., store the resultset in $row;
Now you can dynamically iterate through the resultset:
$results = [];
for($i = 0; $i < count($values); $i++)
{
$string = "v"+ $i;
$results[] = $row[$string];
}

How do I update multiple records in a table with a single MySQL query?

I would like to update multiple records in a MySQL table using a single query. Basically, this is a tasks table, which has assignments for different people on different dates. When these assignments are changed and submitted via the Online form there is a lot of POST data that gets submitted (pretty much all the pending assignments). I've written an algorithm that sorts through all this information and gets what I want out of it, but I'm stuck on writing the query to update the MySQL table:
// Find the modified records and save their information
$update = 0;
for ( $n = 0; $n < $total_records; $n++ )
{
if ( $_POST['update'.$n] == true )
{
$updates_arr[$update] = array( intval($_POST['user_id'.$n]), intval($_POST['task'.$n]), $_POST['date'.$n] );
$update++;
}
}
if ( $mysql_db = OpenDatabase() )
{
$query = "UPDATE tasks_tbl";
if ( $updates_arr[0] )
{
$query .= " SET task = ".$updates_arr[0][1]." WHERE user_id = ".$updates_arr[0][0]." AND date = ".$updates_arr[0][2];
}
for ( $n = 1; $n < $updates; $n++ )
{
$query .= ", SET task = ".$updates_arr[$n][1]." WHERE user_id = ".$updates_arr[$n][0]." AND date = ".$updates_arr[$n][2];
}
$result = mysql_query( $query, $mysql_db );
if ( $result )
{
$page .= "<p>Success!</p>\n\n";
}
else
{
$page .= "<p>Error: ".mysql_error()."</p>\n\n";
}
}
This is the query that is generated:
UPDATE tasks_tbl
SET task = 1
WHERE user_id = 16
AND date = 2010-05-05,
SET task = 1
WHERE user_id = 17
AND date = 2222-02-22
Any suggestions would be appreciated. Thanks.
You can generate a query like this:
UPDATE tasks_tbl SET task=1 WHERE
(user_id=16 AND date='2010-05-05') OR
(user_id=17 AND date='2010-02-22')
There are hacks to avoid using (... and ...) or (... and ...) constructs (concatenate fields and params: "concat(user_id, date) = '". $user_id. $date. "'", but they work a bit slower.
The PHP code:
for ($i = 0; !empty($_POST['update'. $i]; $i++)
if (intval($_POST['task'.$i]) == 1)
$cond[] = '(user_id='. intval($_POST['user_id'. $i]).
' and date=\''. mysql_real_escape_string($_POST['date'.$i]). '\')';
$query = 'UPDATE tasks_tbl SET task=1 WHERE '. implode(' OR ', $cond). ')';
Edit: I don't quite understand why you need to do that in a single query. How many values task can have? 1, 2, 3, or many more? With 3 values, you can use nested IF(...) functions:
UPDATE tasks_tbl SET task=if('. <imploded tasks with value 1>. ', 1, if('.
<tasks with value 2>. ', 2, if('. <tasks with 3>. ', 3,
task))) /* leave as is otherwise */
Or you may put a simple loop on the code I've given:
for ($j = 1; $j <= 3; $j++)
for ($i = 0; !empty($_POST['update'. $i]; $i++)
if (intval($_POST['task'.$i]) == 1)
$cond[] = '(user_id='. intval($_POST['user_id'. $i]).
' and date=\''. mysql_real_escape_string($_POST['date'.$i]). '\')';
mysql_query('UPDATE tasks_tbl SET task=1 WHERE '. implode(' OR ', $cond). ')');
I disagree with your architecture here, but the following should work. Use at your own risk:
UPDATE
Tasks_Table
SET
task =
CASE
WHEN user_id = 16 AND date = 2010-05-05 THEN 1
WHEN user_id = 17 AND date = 2222-02-22 THEN 1
...
END
WHERE
(user_id = 16 AND date = 2010-05-05) OR
(user_id = 17 AND date = 2222-02-22) OR
...
In your example you have task = 1 in all cases, but with the CASE statement you can change them to be what you need for each case. I'll leave the string building to you.
I would prefer to use a prepared query and loop over the data (inside a transaction if needed). That makes it simpler to understand, which is better for maintainability.
Your code smells of sql injection insecurity, too, which prepared queries would eliminate.
See: http://www.php.net/manual/en/mysqli.prepare.php or even better with PDO prepare:
Thanks for the suggestions, everyone. I ended up going with the multiple queries, as it apparently was not going to be as simple to do, as I had hoped.
foreach ( $updates_arr as $record => $data ):
$query = "UPDATE tasks_tbl";
$query .= " SET task = ".$data[1];
$query .= " WHERE task_id = ".$data[0];
$result = mysql_query( $query, $mysql_db );
if ( !$result )
{
break;
}
endforeach;
Are you looking for this:
UPDATE tasks_tbl
SET task = 1
WHERE (user_id = 16 AND date = 2010-05-05)
OR (user_id = 17 AND date = 2222-02-22)
Or you are trying to set 'task' to different values in different rows with a single statement?
The latter is just not possible
I don't think this is possible with one statement. You will need to create separate UPDATE statements:
UPDATE tasks_tbl SET task = 1 WHERE user_id = 16 AND date = 2010-05-05;
UPDATE tasks_tbl SET task = 1 WHERE user_id = 17 AND date = 2222-02-22
You can pass them into mysql_query() as one string separated by ';' if you set mysql to accept multiple queries:
Multiple queries seem to be supported.
You just have to pass flag 65536 as
mysql_connect's 5 parameter
(client_flags)

Categories