This question already has an answer here:
Syntax error due to using a reserved word as a table or column name in MySQL
(1 answer)
Closed 5 years ago.
I have the MySQL table that has filename and description fields.
Then, I wrote this code to do LIKE search.
However my poor code cannot conduct what I want to do.
Error message says
Syntax error or access violation.
PHP 7.0 / MySQL 5.0.95 is my server's.
$keywords = str_replace( "\xc2\xa0", " ", $keywords );
$keywords = preg_replace("/[\s]+/", " ", trim($keywords));
$keywordsarray = array_unique(explode(' ', $keywords));
$sql1 = "SELECT * FROM file_table WHERE ";
$sql2 = array();
$key = array();
foreach ($keywordsarray as $word) {
$sql2[] = " (filename LIKE ? OR describe LIKE ? )";
$key[] = '%'.$word.'%';
$key[] = '%'.$word.'%';
}
$builtsql = $sql1.implode(' AND ', $sql2);
$query = $db->prepare($builtsql);
$query->execute($key);
Could you give me good ideas? Thanks.
The issue is caused by not escaping the reserved word describe in your query.
You should be able to resolve the Syntax error issue by wrapping the column name(s) in identifier quotes (backtick).
$sql2[] = " (`filename` LIKE ? OR `describe` LIKE ? )";
Related
This question already has an answer here:
How to ignore a parameter in a prepared mysqli query in PHP?
(1 answer)
Closed 4 years ago.
For example, we have a mysqli query for select:
$sql = "SELECT * FROM table WHERE cat = 1";
And want to append some extra query to above query based on query string, I tried something like this: (This is just sample, not my Original code)
$keyw = $_GET["k"];
if($keyw){
$cleanKeyw = mysqli_real_escape_string($connection, $keyw);
$addQ= "AND name LIKE '%$cleanKeyw%' OR text LIKE '%$cleanKeyw%'";
} else {
$addQ= "";
}
$sql = "SELECT * FROM table WHERE cat = 1 $addQ";
Not this one, I almost have 10 more statment that want to append to current query
I want to add query if k query string is set, it works but I want to be sure, is it safe or right way to do this? because it's based on my logic and I'm newbie on php and don't know there is technical way to do this?
Also I want to know is there a way to do this via prepared statments ?
Unfortunately most answers to this will be too broad. There is no right or wrong way, and you have escaped your inputs (which is great).
You could consider building your wheres as an array, then imploding them together.
$wheres = [];
$wheres[] = 'cat = 1';
if ($keyw) {
// escape etc
$wheres[] = 'name LIKE '%$cleanKeyw%' OR text LIKE '%$cleanKeyw%''
}
$wheres = implode(" AND ", $wheres);
$sql = "SELECT * FROM table WHERE $wheres";
You could then add lots more $wheres[] as you go along.
I am inserting data from a excel sheet but i receive error and it looks like it is breaking because the value contain a space character in between. As far as i remember space characters allowed in VARCHAR(200)
This is the code i am using
//CREATE SQL QUERY FOR INSERTING DATA IN DATABASE
$sql = "INSERT INTO ".$month."_".$year."(";
foreach($sheetData[1] as $columnName){
$sql .= preg_replace('#[ ]#', '_',$columnName). ",";
}
$sql = rtrim($sql, ',');//REMOVES COMMA FROM END OF THE STRING
$sql .= ")";
//
$sql .= " VALUES((";
for($i=2;$i < count($sheetData);$i++){
foreach($sheetData[$i] as $columnName){
$sql .= $columnName.",";
}
$sql = rtrim($sql,',');//
$sql .= "),";
}
$sql = rtrim($sql,',');//
$sql .= ")";
echo $sql;
$query = mysqli_query($conn,$sql) or die(mysqli_error($conn));
After loops this is how my SQL QUERY look
INSERT INTO December_2015(S_No,Zone,State,City2,VM_Town,Distibutor_Code,Distributor_Name,Dealer_Code,Dealer_Name,Category,Address,Location,Contact,Mobile_No,Visit_1,Visit_2,Visit_3,Visit_4,Visit_5,Visit_6) VALUES( (1,South,Telanagana,Hyderabad,Y,1006704,Sai Santhoshi Enterprises,TG000999,Sree Laxmi Mobiles,A,F4,anthem Arcade,gujarathi Galli,koti ,Koti,Rajesh,8790575680,7-Nov,18-Nov,28-Nov))
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 'Santhoshi Enterprises,TG000999,Sree Laxmi Mobiles,A,F4,anthem Arcade,gujarathi G' at line 1
It says near 'Santhoshi Enterprises ... ' before that there is a space character
You have two "(" instead of one after "VALUES"
Akash,
Didn't you asked a question just a while ago regarding same/similar code with a different error you got, here at: How to loop inside a variable ?!
By the looks of it in general you write messy code, and you are having trouble reading/understanding the error messages. So I'm gonna guess you are new at this.
Here are some good reads for you:
Top 15+ Best Practices for Writing Super Readable Code
PHP the right way
When all said and done, here is your code broken down into more readable segments:
// prepare dummy data
$month = date('M');
$year = date('Y');
$sheetData = array(
array('data00', 'data01')
,array('col1', 'col2', 'col3', 'col4', 'col5', 'col6')
,array('data20', "data21")
,array('data30', 'data31')
,array('data40', 'data41')
);
// prepare vars
$tableName = "{$month}_{$year}";
$dataCount = count($sheetData);
// prepare columns
$columnsSQL = "";
foreach ($sheetData[1] as $columnName) {
// wrap with ` ticks
$columnsSQL .= '`'. preg_replace('#[ ]#', '_', $columnName).'`'.',';
}
$columnsSQL = rtrim($columnsSQL, ',');
// prepare values
$valuesSQL = "";
for ($i=2;$i < $dataCount;$i++) {
foreach($sheetData[$i] as $columnValue){
$valuesSQL .= "'{$columnValue}', ";
}
}
$valuesSQL = rtrim($valuesSQL, ', ');
$SQL = "
INSERT INTO {$tableName}( {$columnsSQL} )
VALUES ( {$valuesSQL} )";
At the end you end up with something like this:
INSERT INTO Nov_2015( `col1`,`col2`,`col3`,`col4`,`col5`,`col6` )
VALUES ( 'data20', 'data21', 'data30', 'data31', 'data40', 'data41' )
Additional note and tips:
Considering that you said you are reading data from excel sheet... Never trust input data without some tests/checks/validation. Not just because of security but stability and in general you don't want things breaking.
Those excel tables could be manually made which automatically means its prone for human error, so you can't be always 100% sure what are you gonna get.
Consider using PDO and prepared statements (security reasons, but also good practice)
This question already has answers here:
Google-like Search Engine in PHP/mySQL [closed]
(9 answers)
Closed 1 year ago.
I currently have a search option on my PHP+MYSQL website.
The MYSQL query is currently something like "SELECT pageurl WHERE name LIKE '%$query%'.
The reason I posted here is because I noticed that if the name of one of my products is "Blue Bike" and someone looks for "Bike Blue", no results are returned.
I am looking for a solution to this because I know that if I type on google same word, something appears.
I was thinking to create a PHP function to mix up all the words from the query if the query is having 4 or fewer words, generating around 24 queries.
Is there an easier solution to this?
Thanks for your time
As to not let this go without a working answer:
<?php
$search = 'this is my search';
$searchSplit = explode(' ', $search);
$searchQueryItems = array();
foreach ($searchSplit as $searchTerm) {
/*
* NOTE: Check out the DB connections escaping part
* below for the one you should use.
*/
$searchQueryItems[] = "name LIKE '%" . mysqli_real_escape_string($searchTerm) . "%'";
}
$query = 'SELECT pageurl FROM names' . (!empty($searchQueryItems) ? ' WHERE ' . implode(' AND ', $searchQueryItems) : '');
?>
DB connections escaping
mysqli_:
Keep using mysqli_real_escape_string or use $mysqli->real_escape_string($searchTerm).
mysql_:
if you use mysql_ you should use mysql_real_escape_string($searchTerm) (and think about changing as it's deprecated).
PDO:
If you use PDO, you should use trim($pdo->quote($searchTerm), "'").
use full text search instead of like
full text search based on indexed text and is very faster and beter than using like.
see this article for more information about full text search
What you are looking for is fulltext search.
Try Sphinx, it is very fast and integrates well with MySQL.
Sphinx website
I wrote a function that approaches Google's operation taking into account the double quotes for the elements to search as a whole block. It does NOT take into account the - or * instructions.
table: MySQL table to consider
cols: array of column to parse
searchParams: search to process. For example: red mustang "Florida 90210"
function naturalQueryConstructor($table, $cols, $searchParams) {
// Basic processing and controls
$searchParams = strip_tags($searchParams);
if( (!$table) or (!is_array($cols)) or (!$searchParams) ) {
return NULL;
}
// Start query
$query = "SELECT * FROM $table WHERE ";
// Explode search criteria taking into account the double quotes
$searchParams = str_getcsv($searchParams, ' ');
// Query writing
foreach($searchParams as $param) {
if(strpos($param, ' ') or (strlen($param)<4)) {
// Elements with space were between double quotes and must be processed with LIKE.
// Also for the elements with less than 4 characters. (red and "Florida 90210")
$query .= "(";
// Add each column
foreach($cols as $col) {
if($col) {
$query .= $col." LIKE '%".$param."%' OR ";
}
}
// Remove last ' OR ' sequence
$query = substr($query, 0, strlen($query)-4);
// Following criteria will added with an AND
$query .= ") AND ";
} else {
// Other criteria processed with MATCH AGAINST (mustang)
$query .= "(MATCH (";
foreach($cols as $col) {
if($col) {
$query .= $col.",";
}
}
// Remove the last ,
$query = substr($query, 0, strlen($query)-1);
// Following criteria will added with an AND
$query .= ") AGAINST ('".$param."' IN NATURAL LANGUAGE MODE)) AND ";
}
}
// Remove last ' AND ' sequence
$query = substr($query, 0, strlen($query)-5);
return $query;
}
Thanks to the stackoverflow community where I found parts of this function!
To have a google like search you'd need many database and index nodes, crazy algorithms.. now you come up with a SELECT LIKE ... lol :D
MySQL is slow in searching, you'd need fulltext and index set properly (MyISAM or Aria Engine). Combinations or different entities to search for are almost not implementable properly AND fast.
I'd suggest to setup an Elasticsearch server which is based on Apache's Lucene.
This searchs very fast and is easy to maintain. And you would not have to care about SQL injection and can still use the mysql server fast.
Elasticsearch (or other Lucene based search engines like SolR) can easily be installed on any server because they are written in Java.
Good documentation:
http://www.elasticsearch.org/guide/en/elasticsearch/client/php-api/current/
I would do an explode first:
$queryArray = explode(" ", $query);
and then generate the SQL query something like:
for ($i=0; $i< count($queryArray); $i++) {
$filter += " LIKE '%" + $queryArray[$i] + "%' AND" ;
}
$filter = rtrim ($filter, " AND");
$sql = "SELECT pageurl FROM ... WHERE name " + $filter
(note: haven't tested/run this code)
I've tried this query with both commas and "AND" statements as pictured below. I get a syntax error
Something went wrong.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 'are available 24/7 by phone and email to answer any questions and to assist you ' at line 1
every time I try this query:
$sql = mysql_query("UPDATE general
SET bookabandheading = $_POST[bookabandheading
AND bookaband = $_POST[bookaband]
AND contactus = $_POST[contactus]
AND aboutuslisten = $_POST[aboutuslisten]
AND contactusheading = $_POST[contactusheading]
AND nightclubsheading = $_POST[nightclubsheading]
AND acousticheading = $_POST[acousticheading]
AND schoolsheading = $_POST[schoolsheading]
AND privateheading = $_POST[privateheading]
AND concertsheading = $_POST[concertsheading]
AND festivalsheading = $_POST[festivalsheading]
AND submissions = $_POST[submissions]
AND interns = $_POST[interns]
AND managementbio = $_POST[managementbio]
AND latestnews = $_POST[latestnews]
AND artistofthemonth = $_POST[artistofthemonth]
AND artistofthemonthphoto = $_POST[artistofthemonthphoto]
AND artistofthemonthid = $_POST[artistofthemonthid]
AND listentoourartists = $_POST[listentoourartists]
AND musicianswanted = $_POST[musicianswanted]
AND aboutus = $_POST[aboutus]
AND bshowcases = $_POST[bshowcases]
AND bandavails = $_POST[bandavails]");
The query worked in a different database on another VPS, but I just migrated servers and it no longer works. Any help is greatly appeciated!
While the main problem is that you missed the closing bracket after bookamandheading, still I would like to advise you to refactor this request for example like this:
$keys = array("bookabandheading", "bookaband", "contactus", "aboutuslisten",
"contactusheading", "nightclubsheading", "acousticheading",
"schoolsheading", "privateheading", "concertsheading",
"festivalsheading", "submissions", "interns", "managementbio",
"latestnews", "artistofthemonth", "artistofthemonthphoto",
"artistofthemonthid", "listentoourartists", "musicianswanted",
"aboutus", "bshowcases", "bandavails");
$set = array();
foreach ($keys as $key) {
$set[] = sprintf(" %s = '%s' ", $key, mysql_escape_string($_POST[$key]));
}
$sql = mysql_query("UPDATE general SET " . implode(", ", $set));
It is much easier to maintain and also a bit more secure by escaping the input.
Update: add where statement example
$where = array();
$where[] = sprintf(" some_string = '%s' ", mysql_escape_string($some_string));
$where[] = sprintf(" some_integer = %d ", $some_integer);
$where = " WHERE " . implode(" AND ", $where);
$sql = mysql_query("UPDATE general SET " . implode(", ", $set) . " " . $where);
I see 3 things wrong with this:
Raw POST data in your query - at the very least user mysql_real_escape_string
The parameters look like strings so should have quotes around them
There's no WHERE option, so you'll update every row in that table
You have a few errors:
Syntax error. Change
$_POST[bookabandheading to $_POST[bookabandheading]
This is also incredibly prone to SQL injections. You should be using mysqli, but if you are set on mysql (which is deprecated as of 5.5.0), you should escape each $_POST variable using mysql_real_escape_string().
Each $_POST variable needs to bee parameterized using quotes a well. So, an example:
$_POST['bookabandheading'] (do this for all $_POST variables)
$_POST[bookabandheading
change to
$_POST[bookabandheading]
$tagList = get_the_tag_list('','---','');
$totaltags = explode('---',$tagList);
foreach ($alltags AS $eachtag)
{
$thistag = GetBetween($eachtag,'/tag/','/');
$SQL = "SELECT * FROM table WHERE thetag = '$eachtag'"
$result = mysql_query($SQL, $link) or die(mysql_error());
if(mysql_affected_rows()>0)
{
echo $thistag;
}
}
This is my working code. It works, but I really don't like having the SQL command in the foreach. I assumed it wouldn't be an issue since there's no more than 8 tags on any given page. Is there a more efficient way to code this? (i.e. optimize for 1 mysql command or have less code)
This is my working code. It works, but I really don't like having the SQL command in the foreach. I assumed it wouldn't be an issue since there's no more than 8 tags on any given page. Is there a more efficient way to code this? (i.e. optimize for 1 mysql command or have less code)
Quite simple really:
<?php
// build quotes around the tags, this specific syntax is PHP 5.3+
$alltags = array_map( $alltags, function( $value ) {
return "'" . mysql_real_escape_string( $value ) . "'";
});
$query = 'SELECT * FROM table WHERE thetag IN ( %s );';
$sql = sprintf( $query, implode( ', ', $alltags ) );
echo $sql;
Take a look at the FIND_IN_SET function.