My code contain
SELECT * FROM newchap WHERE company LIKE '%$company%' OR Category LIKE '%$cat%'
It works perfectly however, when the field $company contain empty, it return all result in MYSQL.
How to prevent it?
SELECT *
FROM newchap
WHERE (company LIKE '%$company%' AND company != '') OR Category LIKE '%$cat%'
Since the % wildcard can be any combination of characters, if it's empty you're selecting any company at all; your query in that case is
SELECT * FROM newchap WHERE company LIKE '%%' OR Category LIKE '%$cat%'
You could add an AND condition into the SQL to filter out the case where the company is empty, or you could just check for that in PHP. If this is a common case that should be faster, since it will save you running a query at all.
Also — and this is very important — if there's any chance that $company or $cat could contain user input, you should be using a parameterized SQL query. otherwise you're creating a vulnerability for an SQL injection.
Related
I am trying to refer to a column name to order a query in an application communicating with an Oracle database. I want to use a bind variable so that I can dynamically change what to order the query by.
The problem that I am having is that the database seems to be ignoring the order by column.
Does anyone know if there is a particular way to refer to a database column via a bind variable or if it is even possible?
e.g my query is
SELECT * FROM PERSON ORDER BY :1
(where :1 will be bound to PERSON.NAME)
The query is not returning results in alphabetical order, I am worried that the database is interpreting this as:-
SELECT * FROM PERSON ORDER BY 'PERSON.NAME'
which will obviously not work.
Any suggestions are much appreciated.
No. You cannot use bind variables for table or column names.
This information is needed to create the execution plan. Without knowing what you want to order by, it would be impossible to figure out what index to use, for example.
Instead of bind variables, you have to directly interpolate the column name into the SQL statement when your program creates it. Assuming that you take precautions against SQL injection, there is no downside to that.
Update: If you really wanted to jump through hoops, you could probably do something like
order by decode(?, 'colA', colA, 'colB', colB)
but that is just silly. And slow. Don't.
As you are using JDBC. You can rewrite your code, to something without bind variables. This way you can also dynamically change the order-by e.g.:
String query = "SELECT * FROM PERS ";
if (condition1){
query = query+ " order by name ";
// insert more if/else or case statements
} else {
query = query+ " order by other_column ";
}
Statement select = conn.createStatement();
ResultSet result = select.executeQuery(query);
Or even:
String columnName = getColumnName(input);
Statement select = conn.createStatement();
ResultSet result = select.executeQuery("SELECT * FROM PERS ORDER BY "+columnName);
ResultSet result = select.executeQuery(
"SELECT * FROM PERS ORDER BY " + columnName
);
will always be a new statement to the database.
That means it is, like Thilo already explained, impossible to "reorder" an already bound, calculated, prepared, parsed statement. When using this result set over and over in your application and the only thing, which changes over time is the order of the presentation, try to order the set in your client code.
Otherwise, dynamic SQL is fine, but comes with a huge footprint.
I'm building a simple search engine in PHP that retrieves animal names from a MySQL database when the user searches it.
Say I have the following table:
ID | Name
---------------
1 | Red panda
2 | Okapi
3 | Red fox
When the user inputs "panda" it returns the Red Panda row, when they input "red panda" it again returns the Red Panda row.
But when a user inputs "red" it returns nothing.
However searching "Okapi" does work.
For some reason searching the first word in a multiple made of multiple words doesn't return anything.
The query I'm using to find the data is the following:
"SELECT * FROM example_table WHERE Name LIKE '%%$search'"
If you need to find anything which contains what you're searching for then you should use the % wildcard both before and after your $search in the query.
Hence you should do:
$query = "SELECT * FROM example_table WHERE Name LIKE %$search%";
The way you're currently using will match only those values which have the $search at the end of it.
For instance:
ID | Name
---------------
1 | Red panda
2 | Okapi
3 | Red fox
4 | kaok // added for examples
matching %ka:
won't return anything because kaok and Okapi have something after the ka. With this query you're looking for everything that starts with your expression;
matching %ka%:
will return both kaok and Okapi. With this query you're looking for everything that contains your expression;
matching ka%:
will return only kaok. With this query you're looking for everything that ends with your expression.
Take a look at the MySQL Dev guide about pattern matching.
Of course, as pointed out by Elzo Valugi, in his answer you need to remember to sanitise your inputs to avoid SQL Injections.
You can use it like this:
"SELECT * FROM example_table WHERE Name LIKE '%".$search."%'";
You placed a wildcard at the begin of your like string, so you will find any names which end with the search term.
To search for all names which contain the search term add a wildcard at the end of the like string:
LIKE '%$search%'
It returns nothing because your SQL Query needs to be modified slightly:
Change this
"SELECT * FROM example_table WHERE Name LIKE '%%$search'"
to this:
"SELECT * FROM example_table WHERE Name LIKE '%$search%'"
By adding % on both sides of the searched string, your database will look for any column value that has that word inserted into it.
Let me know if that solved it for you or if there are any more issues!
try this
% wildcard should be like this
$query = "SELECT * FROM example_table WHERE Name LIKE '%$search%'";
A side note, do not aggregate the user input directly to an SQL query. This is totally unsafe practice and leads to SQL injection, in fact all examples shown here are bad practice. Use binding parameters to create your query using mysqli or PDO.
$search = "%". "your_search_term" . "%";
$sth = $dbh->prepare('SELECT *
FROM example_table
WHERE name like :search');
$sth->bindParam(':search', $search, PDO::PARAM_STR, 12);
$sth->execute();
It has been issue with select query.You have to change select query only.
select * from tbl_pets where name like "%'".$data."'%"
and real mysql query
select * from tbl_pets where name like "%red%"
You can take a look here.I have created schema from that you can also check.
http://sqlfiddle.com/#!9/c08b0/1
I think the answer to this may be simple, but being new to SQL I am still growing. Here's my dilemma. I have a php array of options with 10 values. When any one option is selected it is passed into a variable named "spots". I have 10 SQL SELECT statements that pull 1 of 10 different tables. The issue is that I do not know exactly what to do in order to get the SQL to recognize which value was selected and based on which was selected show that specific table data. (This would be easy if I were able to use the JavaScript Switch statement, but I do not know an equivalent for that)
EXAMPLE:
PHP
$spots = ["Report1","Report2","Report3","Report4","Report5","Report6","Report7","Report8","Report9","Report10"];
SQL
SELECT *, FROM Report5
ORDER BY TW ASC;
Now how do I get SQL to loop through an array to find a match, then depending on that match select from a list of commands (for example like a JavaScript switch statement)?
Use variable substitution:
foreach ($spots as $spot) {
$sql = "SELECT * FROM $spot ORDER BY TW ASC";
// perform the SQL query using $sql, do what you want with the results
}
Make sure you've validated that the values in $spots are valid if they're coming from the user. Otherwise you'll be subjecting your code to SQL injection.
I was running a site I purchased that I thought was fairly unhackable. However, after having an attack, I found it was not. He informed me of the vulnerability, however my question is what user input could have been done to get all the users usernames like he did? Here is the code...
$un=$_GET['username'];
$q=$db->query("SELECT * FROM users WHERE login_name='$un' OR username='$un'");
I realize that this is highley hackable. Therefore, I changed the site over to prepared statements to prevent this from happening again. I just want to know what he could have entered to get all the users usernames.
Someone posted the script on github, you can find it here:
https://github.com/sat312/Mafia-Game-Script/blob/master/checkun.php
' OR 1=1;
In the URL:
/yourScript.php?username=%27%20OR%201%3D1%3B
The idea is that since data is mixed with the command, you can just finish the command with data.
You get $un from the user, so I can type anything I want and it'll get substituted into your query. It's called a SQL Injection attack.
Lets say $un = ' OR 1 = 1;-- then your query becomes:
SELECT * FROM users WHERE login_name='' OR 1 = 1;--' OR username='' OR 1 = 1;--'
What will happen? this gets executed:
SELECT * FROM users WHERE login_name='' OR 1 = 1;
This will return every row in the table.
He may have used the GROUP_CONCAT statement in MySql which basically groups a column in multiple rows into a single row (see Can I concatenate multiple MySQL rows into one field? for more information). He may have terminated the original SQL statement or UNIONED it with his own and added a LIMIT and ORDER BY to ensure his result got returned and commented out the remained of the original statement.
This is one possibility, but there are probably a few others.
I created a search engine on my website where user can input whatever they like and show the result. Below is the code I use to get the result but it is not working because of the syntax error.
In my database I have 10 rows, each rows contain 4 columns(id, author, second_author, book_name). My goal is, if the user enter a name that is found in 'author', I want to retrieve that result, 'OR' if they enter a name that is found in book_name I want to retrieve that result and so on for the other columns..
I know the proper way to do this is by using LIKE Operator, but how about if you want to compare the keywords to several columns, what should you do?
I've tried this but was not working:
SELECT * FROM book_list WHERE author OR second_author OR book_name LIKE '%".$search_key."%'
It's just a syntax tweak:
SELECT * FROM book_list
WHERE author LIKE '%".$search_key."%'
OR second_author LIKE '%".$search_key."%'
OR book_name LIKE '%".$search_key."%'
Hope that helps
Your query has an error, you have to search on each column as
SELECT * FROM book_list WHERE author LIKE '%".$search_key."%' OR second_author LIKE '%".$search_key."%' OR book_name LIKE '%".$search_key."%'
I would also like you to be aware that you are at risk of sql injection, have a look here How can I prevent SQL injection in PHP?. You should use prepared statment to avoid any risk