I have a form with two fields. The user can fill in either one or both and the MySQL database should be queried accordingly.
Here is my php code:
$number1 = $_POST['number1'];
$number2= $_POST['number2'];
$set = FALSE;
$query = "SELECT * FROM table";
if (!empty($number1 ))
{
$query .= " WHERE number1 = ".$number1."";
$set = TRUE;
}
if (!empty($number2))
{
$query .= ($set===TRUE ? " AND" : " WHERE") . " number2 = ".$number2."";
}
$data = mysql_query($query) or die("Couldn't execute query. ". mysql_error());
The code works fine if either number1 or both of the fields are filled in. However when only the second field is filled in I get the error:
Couldn't execute query. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
If I echo the query it is shown correctly:
SELECT * FROM table WHERE number2 = entered value
Any help is much appreciated! Thanks!!
have you forget escape values? u can use somthing like this
$fields = array();
if(!empty($_POST['number1'])) {
$fields[] = 'number1='.mysqli_real_escape_string($_POST['number1']);
}
if(!empty($_POST['number2'])) {
$fields[] = 'number2='.mysqli_real_escape_string($_POST['number2']);
}
$sql = "SELECT * FROM table WHERE ".implide(" AND ", $fields);
$data = mysqli_query($query) or die("Couldn't execute query. ". mysql_error());
mysql extension is deprecated, use mysqli instead
try this
$number1 = $_POST['number1'];
$number2= $_POST['number2'];
$set = FALSE;
$query = "SELECT * FROM table";
if (!empty($number1 ))
{
$query .= " WHERE number1 = ".$number1."";
$set = TRUE;
}
if (!empty($number2))
{
if($set==FALSE)
$query .= " WHERE number2 = ".$number2;
else
$query .= " AND number2 = ".$number2;
}
I think you get the error because of the assignment. You wrote $set===TRUE, its == not ===
The error is here:
if (!empty($number2))
{
$query .= ($set===TRUE ? " AND" : " WHERE") . " number2 = ".$number2."";
}
Related
I want to retrieve data from three tables using some condition and then insert/update in another three tables. This is a very simple process, the script of which is developed in php. But the catch is that the records retrieved from each table is 100k+. PHP script runs only with small number of records and gives time out error for large data. Can anyone please suggest how to solve this issue. All the three tables data needs to be fetched at runtime. Below is my php script which gives timeout error
switch($action){
case 'tequipebudget':
$oldPresta = budPrestaDataTransfer::getOldPresta('tequipebudget');
$budProviderBudget = budPrestaDataTransfer::updatebudProviderBudget($oldPresta, 'budproviderbudget', 3);
break;
case 'tequipebudgetjum':
$oldPrestaJum = budPrestaDataTransfer::getOldPresta('tequipebudgetjum');
$budProviderBudgetJum = budPrestaDataTransfer::updatebudProviderBudget($oldPrestaJum, 'budproviderbudgetjum', 3);
break;
case 'tequipebudgetavhisto':
$oldPrestaAvHisto = budPrestaDataTransfer::getOldPresta('tequipebudgetavhisto');
$budProviderBudgetAvHisto = budPrestaDataTransfer::updatebudProviderBudget($oldPrestaAvHisto, 'budproviderbudgetavhisto', 3);
break;
}
static public function getOldPresta($table) {
$sql = "SELECT Annee, CodeEntite, CodeProjet, MtBudgetAEquipeKE, projet_id";
if($table == 'tequipebudgetavhisto') {
$sql .= " ,avenant_id ";
}
$sql .= " FROM ".$table." WHERE Annee < 2020 ";
$dbObj = budPDO::getInstance();
$prestaList = $dbObj->getAllResults($sql);
return $prestaList;
}
static public function updatebudProviderBudget($prestaList, $table, $autreId) {
foreach($oldPresta as $key=>$val) {
$sql = "SELECT count(*) as cnt FROM ".$table." WHERE Annee = '".$val['Annee']."' AND CodeEntite = '".$val['CodeEntite']."' AND
CodeProjet = '".$val['CodeProjet']."' AND projet_id = '".$val['projet_id']."' AND provider_id = '".$oldPresta['AuterId']."' ";
$dbObj = budPDO::getInstance();
$res = $dbObj->getOneRow($sql);
if($res['cnt'] == 0){ // record does not exists in table
$update = "INSERT INTO ".$table." SET Annee = '".$val['Annee']."', CodeEntite = '".$val['CodeEntite']."',
CodeProjet = '".$val['CodeProjet']."', cost = '".$val['MtBudgetAEquipeKE']."' ,
projet_id = '".$val['projet_id']."', provider_id = '".$autreId."',
addedon_date = '".NOW_CONST."' ";
if($table == 'budproviderbudgetavhisto') {
$update .= " ,avenant_id= '".$val['avenant_id']."' ";
}
}else {
$update = "UPDATE ".$table." SET Annee = '".$val['Annee']."', CodeEntite = '".$val['CodeEntite']."',
CodeProjet = '".$val['CodeProjet']."', cost = '".$val['MtBudgetAEquipeKE']."' ,
projet_id = '".$val['projet_id']."', provider_id = '".$autreId."',
modifiedon_date = '".NOW_CONST."' ";
if($table == 'budproviderbudgetavhisto') {
$update .= " ,avenant_id= '".$val['avenant_id']."' ";
}
$update .= " WHERE Annee = '".$val['Annee']."' AND CodeEntite = '".$val['CodeEntite']."' AND
CodeProjet = '".$val['CodeProjet']."' AND projet_id = '".$val['projet_id']."' AND provider_id = '".$autreId."' ";
if($table == 'budproviderbudgetavhisto') {
$update .= " AND avenant_id= '".$val['avenant_id']."' ";
}
}
//echo "update -- " . $update. "<br><br>";
$sth = $dbObj->pdo->prepare($update);
$exec = $sth->execute();
}
}
You could increase the timeout in your PHP settings.
ini_set('max_execution_time','{number of seconds}');
Then you will probably also have to increase the memory limit.
ini_set('memory_limit', '2GB');
But it would be better to leave large data logic to the database. So if I were you, I would write a stored procedure / function and execute it with PHP only exec
I'm trying to create a filter in mysql and php. In my database, I have many fields like : name, phoneNumber, email... And even if I do something like
if(!empty($_POST['name'])){
$name=$_POST['name']
}
if(!empty($_POST['phoneNumber'])){
$phoneNumber= $_POST['phoneNumber']
}
if(!empty($_POST['email'])){
$email=$_POST['email']
}
If someone only enters the name field, how do I do to not include the other fields in the query?
$query=query("SELECT * FROM clients WHERE clientName=$clientName && phoneNumber=$phoneNumber && email=$email)
you can try something like given below
if(!empty($_POST['name'])){
$name=$_POST['name'];
$query="SELECT * FROM clients WHERE clientName='$name'";
}
if(!empty($_POST['phoneNumber'])){
$phoneNumber= $_POST['phoneNumber'];
$query.= " AND phoneNumber='$phoneNumber'";
}
if(!empty($_POST['email'])){
$email=$_POST['email'];
$query.= " AND email='$email'";
}
NOTE:use prepared query because this is open to sql injection attack.
this is demonstration only.
What I do for this sort of thing is have all the search terms sent to post within a single JSON object. So in javascript I collect all the search inputs and have an object where each key corresponds to the name of the input and each value corresponds to the val. For example in jQuery
var searchObj = {};
$(".searchInput").each(function() {
searchObj[$(this).attr('name')] = $(this).val();
});
var searchJSON = JSON.stringify(searchObj);
//later send searchJSON to php
//in php
$seachObj = json_decode($_POST["searchJSON"], true);
$sql = "SELECT * in CLIENTS WHERE ";
foreach($searchObj as $key => $val) {
$sql .= "$key = '$val' AND ";
}
$sql .= "1";
NOW THIS IS TOTALLY UNSECURED!!! Only included so that it's clear. Better to use PDO or mysqli, to use prepared statements. Like this:
$seachObj = json_decode($_POST["searchJSON"], true);
$sql = "SELECT * in CLIENTS WHERE ";
$vals = [];
foreach($searchObj as $key => $val) {
$vals[] = $val;
$sql .= "$key = ? AND ";
}
$sql .= "1";
//learn more about PDO to get this part
$stmt = $pdo->prepare($sql);
$stmt->execute($vars);
I think this would do it.
$condition = "";
if(!empty($_POST['name'])){
$name=$_POST['name'];
$condition .= " AND clientName LIKE ".$name;
}
if(!empty($_POST['phoneNumber'])){
$phoneNumber= $_POST['phoneNumber'];
$condition .= " AND phoneNumber ='".$phoneNumber."'";
}
if(!empty($_POST['email'])){
$email=$_POST['email'];
$condition .= " AND email='".$email."'";
}
if(!empty($condition)){
$query="SELECT * FROM clients WHERE ".ltrim($condition," AND");
}else{
$query="SELECT * FROM clients";
}
The Aim
Hi, I'm trying to shorten my code by building the query dynamically based on the $_GET. Current I have every possible If statement with the relevant SELECT query. However I would like to create a dynamic system for feature updates.
Current Progress
//Set Filter based on url
if ($_GET[GAME] != "") { $gameFilter = $_GET[GAME]; } else { $gameFilter = ''; }
if ($_GET[Region] != "") { $regionFilter = $_GET[Region]; } else { $regionFilter = ''; }
if ($_GET[Console] != "") { $consoleFilter = $_GET[Console]; } else { $consoleFilter = ''; }
$result = get_matchfinder($gameFilter, $regionFilter, $consoleFilter);
//The Function
function get_matchfinder($gameFilter, $regionFilter, $consoleFilter) {
//Set Varibles
$database = 'matchFinder';
$order = 'DESC';
$limit = '20';
//Query Function
$connection = connection();
$sql = 'SELECT * FROM '. $database .' WHERE game = "'.$gameFilter.'" AND region = "'.$regionFilter.'" AND console = "'.$consoleFilter.'" ORDER BY ID '. $order .' LIMIT '. $limit .'';
$response = mysqli_query($connection, $sql);
//Return
return $response;
}
Problem
Currenly it works when all of the filters are active but if one of them isn't the whole query fails, I know thats because it is try to SELECT something matching ''.
So my questions is how do I make it search for all when that filters is not set?
You should build the query parts depending on the length of the filter:
$sql = '
SELECT * FROM '.$database.'
';
$filters = array();
if (strlen($gameFilter) > 0) {
$filters[] = 'game = "'.mysqli_escape_string($connection, $gameFilter).'"';
}
if (strlen($regionFilter) > 0) {
$filters[] = 'region = "'.mysqli_escape_string($connection, $regionFilter).'"';
}
if (strlen($consoleFilter ) > 0) {
$filters[] = 'console= "'.mysqli_escape_string($connection, $consoleFilter).'"';
}
if (count($filters) > 0) {
$sql .= ' WHERE '.implode(' AND ', $filters);
}
if (strlen($oder) > 0) {
$sql .= ' ORDER BY ID '.$order;
}
if ($limit > 0) {
$sql .= ' LIMIT '.$limit;
}
$response = mysqli_query($connection, $sql);
What you're doing there is building up an array of conditions, based on the length of the condition. If the condition's input is an empty string, it isn't added to the array. At the end, if there are any filters, use implode to bind the conditions into a string. The way implode works, if there's only one condition, the glue string isn't used.
It also bears mentioning that you are exposing yourself to SQL injection. The above code shows the use of mysqli_escape_string to escape the input, but you should look in to parameterized queries to take full precaution: http://php.net/manual/en/mysqli.quickstart.prepared-statements.php -- the above sample would only be slightly different if you used paraterized queries, but significantly more safe.
Documentation
strlen - http://php.net/manual/en/function.strlen.php
implode - http://php.net/manual/en/function.implode.php
Mysql parameterized queries - http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
You would have to build your search dynamically
You could start your base query with
$sql='SELECT * FROM '. $database .' WHERE 1=1'
Then, if $gameFilter!="", append to your existing $sql string with "and game=$gameFilter"
The syntax for appending would be like this
if ($gameFilter!="")
{
$sql.=' and game=$gameFitler'
}
and so on checking for all of your search conditions.
Make you string like this
$sql = 'SELECT * FROM '. $database .' WHERE 1=1 {0} {1} {2}'
if ( $gameFilter <> '')
$sql = str_replace("{0}", "AND game = '".$gameFilter."'" , $sql);
else
$sql = str_replace("{0}", "" , $sql);
if ( $regionFilter <> '')
$sql = str_replace("{1}", "AND region = '".$regionFilter."'" , $sql);
else
$sql = str_replace("{1}", "" , $sql);
if ( $consoleFilter <> '')
$sql = str_replace("{2}", "AND console = '".$consoleFilter."'" , $sql);
else
$sql = str_replace("{2}", "" , $sql);
My script is quitting on SQL calls that should not have an issue. One of the queries that is failing to update is:
UPDATE dist_comp.private_schools SET mail_address = '1351 Royalty Dr', city = 'Alabaster', state = 'AL',zip_code = 35007,phone = '2056633973' WHERE school_name = 'Kingwood Christian School' AND city = 'Alabaster'
When I run the same query in MySQL workbench, I get
Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Queries and reconnect.
Is this the reason why my script is quitting?
<?php
require_once('connect.php');
function schoolInfo($school_name,$city){
$data = array();
$counter = 0;
$handle = fopen("k12privateschools_loc_0813.csv","r") or exit('doesnt work');
fgetcsv($handle) or exit('fgetcsv issue');
while( ($line = fgetcsv($handle)) !== false) {
$data[] = $line;
///echo ("Does schoolname and city match: " . addslashes($data[$counter][2]). ":" . $school_name . " ; " . addslashes($data[$counter][4]). ":" . $city . "\n");
if (addslashes($data[$counter][2])==$school_name && addslashes($data[$counter][4])==$city){
//echo ('match');
if($data[$counter][13] != ""){
$mail_address = $data[$counter][12];
$city= $data[$counter][13];
$state= $data[$counter][14];
$zip_code= $data[$counter][15];
$zip_4= $data[$counter][16];
}else{
$mail_address = $data[$counter][3];
$city= $data[$counter][4];
$state= $data[$counter][5];
$zip_code= $data[$counter][6];
$zip_4= $data[$counter][7];
}
$phone= $data[$counter][8];
$query= "UPDATE dist_comp.private_schools SET
mail_address = '".$mail_address."',
city = '".$city."',
state = '".$state."',";
if($zip_code != ""){
$query.="zip_code = ".$zip_code.",";
}
if($zip_4 != ""){
$query.="zip_4 = ".$zip_4.",";
}
$query.= "phone = '".$phone."'
WHERE school_name = '".$school_name."' AND city = '" .$city . "'";
mysqli_query($con,$query);
if(mysqli_affected_rows($con)==0){
exit($query . "\n ");
}
//echo $query;
}//end if counter \
else{
//echo("no match");
}
$counter++;
}//end read lines from file
}
echo "starting import \n";
//Query for all school names
$sql2 = mysqli_query($con,"SELECT school_name,city FROM dist_comp.private_schools") or exit('query issue second');
while($row = mysqli_fetch_array($sql2)){ //this line is making it take a really long time
$school_name= addslashes($row['school_name']);
$city = addslashes($row['city']);
schoolInfo($school_name,$city);
}//end while fetch array
//}
echo "Import finished";
?>
Try to disable safe update using this line before your query :
mysqli_query($con,"SET sql_safe_updates=0");
Or use :
$query="SET sql_safe_updates=0";
$query.= "UPDATE dist_comp.private_schools SET
mail_address = '".$mail_address."',
city = '".$city."',
state = '".$state."';";
mysqli_multi_query($con,$query);
or in MySQL WorkBench:
Edit -> Preferences -> SQL Queries
Uncheck Forbid UPDATE and DELETE statements without a WHERE clause
(safe updates)
Query --> Reconnect to Server
$query = 'SET SQL_SAFE_UPDATES=0;';
$query .= 'custom query here;';
$query .= 'SET SQL_SAFE_UPDATES=1;';
I'm fairly new to php and coding in general.
I have a series of conditions I need to test if they are set.
They are $option1, $option2, $option3
if (isset($option1)){
if (isset($option2)){
if (isset($option3)){
$query = "SELECT *
FROM Group
WHERE FirstOption = '$option1' AND SecondOption = '$option2' AND ThirdOption = '$option3'";
}
else {
$query = "SELECT *
FROM Group
WHERE FirstOption = '$option1' AND SecondOption = '$option2";
}
}
else {
$query = "SELECT *
FROM Group
WHERE FirstOption = '$option1' AND ThirdOption = '$option3";
}
}
else {
// .. snip, much more duplicated code ..
}
So the issue here is I need unique queries for mysql based upon whether the conditions are set or not. But they are within each other a great deal and I actually have 7 lots of options, so the branching is absolutely massive! I stopped at three after nearly confusing myself.
There has to be a far superior way of writing this - could anybody help me understand better?
No dynamic sql building needed. Just use logic.
SELECT *
FROM Group
WHERE (FirstOption = '$option1' or '$option1' = '')
AND (SecondOption = '$option2' or '$option2' = '')
AND (ThirdOption = '$option3' or '$option3' = '')
Ideally you would use placeholders and prepared statements, but the above is most clear for instructional purposes.
In case anyone is curious - there's no significant query overhead to this. Any modern database engine will optimize the '$option1' = '' expression into a constant value, evaluating it to boolean only once.
My ordinary way:
$cond=array();
$bind=array();
if(isset($option1))
{
$cond[]="FirstOption=?";
$bind[]=$option1;
}
if(isset($option2))
{
$cond[]="SecondOption=?";
$bind[]=$option2;
}
if(isset($option3))
{
$cond[]="ThirdOption=?";
$bind[]=$option3;
}
$sql="SELECT * FROM `group`";
if(count($cond)>0) $sql.=" WHERE ".implode(" AND ",$cond);
$stmt=$mysqli->prepare($sql);
if(count($bind)>0)
{
foreach($bind as $idx=>$val)
{
$stmt->bind_param("s",$bind[$idx]);
}
}
$baseSQL = "SELECT * FROM Group";
if(isset($option1)){
sprintf("%s world. Day number %u",$str,$number);
$whereSQL[] = sprintf("FirstOption = '%s'",mysqli_real_escape_string($mysqli,$option1));
}
if(isset($option2)){
$whereSQL[] = sprintf("SecondOption = '%s'",mysqli_real_escape_string($mysqli,$option2));
}
if(isset($option3)){
$whereSQL[] = sprintf("ThirdOption = '%s'",mysqli_real_escape_string($mysqli,$option3));
}
if(isset($whereSQL)){
$query = $baseSQL ." WHERE " . implode(" AND ",$whereSQL);
}
Try this
$sql = "Select * from Group where 1=1 ";
$whr = "";
if(isset($option1)){
$whr .= " and FirstOption = $option1";
}
if(isset($option2)){
$whr .= " and SecondOption = $option2";
}
if(isset($option3)){
$whr .= " and ThirdOption = $option3";
}
// nth element ...
if(isset($optionN)){
$whr .= " and nTHOption = $optionN";
}
$sql .= $whr;
This way you can add any numbers of options to your query in where condition.
if(isset($option1)||isset($option2)||isset($option3)){
$sqlToAdd = (isset($option1)?" FirstOption=$option1":"");
$sqlToAdd .= ($sqlToAdd==""?"":" AND ").(isset($option2)?" SecondOption=$option2":"");
$sqlToAdd .= ($sqlToAdd==""?"":" AND ").(isset($option3)?" ThirdOption=$option3":"");
$sql = "SELECT *
FROM Group
WHERE $sqlToAdd";
}