Use of LIKE clause in sql prepared statement, spring, SimpleJDBCTemplate - sql

I have the following sql prepared statement:
SELECT * FROM video WHERE video_name LIKE ?
Im using spring and jdbc.
i have a method, where term is a searchterm, sjt is a SimpleJdbcTemplate, VideoMapper is a RowMapper and searchForTermQuery is the string from above
...
return sjt.query(searchForTermQuery, new VideoMapper(), term);
My table has 2 videos that match the term.
However when I run the query none is found. I get an empty List.
I tried playing with % around the question mark, but it only gave badGrammarExceptions.

You need to put the % around the value itself, not around the placeholder (the question mark).
So:
return sjt.query(searchForTermQuery, new VideoMapper(), "%" + term + "%");

Related

JPA native query gives incorrect output

I know this may sound silly but I've been stuck on this problem for too long!
I'm querying a PostgreSQL repository through JPA using native SQL queries. One of my queries looks like this:
#Query(value = "select * from gs where ?1 = ?2", nativeQuery = true)
public List<GsJsonStore> matchJson(String term, String value);
I'm testing the function using :
List<GsJsonStore> list = repo.matchJson("subject", "'Sub'");
The list is empty on running the query, however when I run the same query through PSQL command line using:
select * from gs where subject = 'Sub';
I get the correct output, records contatining the key-value pair are returned.
Where am I making the mistake?
You can't use parameter for column name. Your query resolves to
select * from gs where 'subject' = '''Sub'''
EDIT: just saw #pozs already posted the same in comment

SQL wildcards via Ruby

I am trying to use a wildcard or regular expression to give some leeway with user input in retrieving information from a database in a simple library catalog program, written in Ruby.
The code in question (which currently works if there is an exact match):
puts "Enter the title of the book"
title = gets.chomp
book = $db.execute("SELECT * FROM books WHERE title LIKE ?", title).first
puts %Q{Title:#{book['title']}
Author:#{book['auth_first']} #{book['auth_last']}
Country:#{book['country']}}
I am using SQLite 3. In the SQLite terminal I can enter:
SELECT * FROM books WHERE title LIKE 'Moby%'
or
SELECT * FROM books WHERE title LIKE "Moby%"
and get (assuming there's a proper entry):
Title: Moby-Dick
Author: Herman Melville
Country: USA
I can't figure out any corresponding way of doing this in my Ruby program.
Is it not possible to use the SQL % wildcard character in this context? If so, do I need to use a Ruby regular expression here? What is a good way of handling this?
(Even putting the ? in single quotes ('?') will cause it to no longer work in the program.)
Any help is greatly appreciated.
(Note: I am essentially just trying to modify the sample code from chapter 9 of Beginning Ruby (Peter Cooper).)
The pattern you give to SQL's LIKE is just a string with optional pattern characters. That means that you can build the pattern in Ruby:
$db.execute("SELECT * FROM books WHERE title LIKE ?", "%#{title}%")
or do the string work in SQL:
$db.execute("SELECT * FROM books WHERE title LIKE '%' || ? || '%'", title)
Note that the case sensitivity of LIKE is database dependent but SQLite's is case insensitive so you don't have to worry about that until you try to switch database. Different databases have different ways of dealing with this, some have a case insensitive LIKE, some have a separate ILIKE case insensitive version of LIKE, and some make you normalize the case yourself.

Parse SQL with REGEX to find Physical Update

I've spent a bit of time trying to bend regex to my will but its beaten me.
Here's the problem, for the following text...
--to be matched
UPDATE dbo.table
UPDATE TOP 10 PERCENT dbo.table
--do not match
UPDATE #temp
UPDATE TOP 10 PERCENT #temp
I'd like to match the first two updates statements and not match the last two update statements. So far I have the regex...
UPDATE\s?\s+[^#]
I've been trying to get the regex to ignore the TOP 10 PERCENT part as its just gets in the way. But I haven't been successful.
Thanks in advance.
I'm using .net 3.5
I assume you're trying to parse real SQL syntax (looks like SQL Server) so I've tried something that is more suitable for that (rather than just detecting the presence of #).
You can try regex like:
UPDATE\s+(TOP.*?PERCENT\s+)?(?!(#|TOP.*?PERCENT|\s)).*
It checks for UPDATE followed by optional TOP.*?PERCENT and then by something that is not TOP.*?PERCENT and doesn't start with #. It doesn't check just for the presence of # as this may legitimately appear in other position and not mean a temp table.
As I understand it, you want a regex to interact with SQL code, not actually querying a database?
You can use a negative look ahead to check if the line has #temp:
(?m)^(?!.*#temp).*UPDATE
(?!...) will fail the whole match if what's inside it matches, ^ matches the beginning of the line when combined with the m modifier. (?m) is the inline version of this modifier, as I don't know how/where you plan on using the regex.
See demo here.
#Robin's solution is much better but in case you needed regex with some simplier mechanisms employed I give you this:
UPDATE\s+(TOP\s+10\s+PERCENT\s+)?[a-z\.]+
sqlconsumer, here's a fully functioning C# .NET program. Does it do what you're looking for?
using System;
using System.Text.RegularExpressions;
class Program {
static void Main() {
string s1 = "UPDATE dbo.table";
string s2 = "UPDATE TOP 10 PERCENT dbo.table";
string s3 = "UPDATE #temp";
string s4 = "UPDATE TOP 10 PERCENT #temp";
string pattern = #"UPDATE\s+(?:TOP 10 PERCENT\s+)?dbo\.\w+";
Console.WriteLine(Regex.IsMatch(s1, pattern) );
Console.WriteLine(Regex.IsMatch(s2, pattern));
Console.WriteLine(Regex.IsMatch(s3, pattern));
Console.WriteLine(Regex.IsMatch(s4, pattern));
Console.WriteLine("\nPress Any Key to Exit.");
Console.ReadKey();
} // END Main
} // END Program
The Output:
True
True
False
False

SQL query to bring all results regardless of punctuation with JSF

So I have a database with articles in them and the user should be able to search for a keyword they input and the search should find any articles with that word in it.
So for example if someone were to search for the word Alzheimer's I would want it to return articles with the word spell in any way regardless of the apostrophe so;
Alzheimer's
Alzheimers
results should all be returned. At the minute it is search for the exact way the word is spell and wont bring results back if it has punctuation.
So what I have at the minute for the query is:
private static final String QUERY_FIND_BY_SEARCH_TEXT = "SELECT o FROM EmailArticle o where UPPER(o.headline) LIKE :headline OR UPPER(o.implication) LIKE :implication OR UPPER(o.summary) LIKE :summary";
And the user's input is called 'searchText' which comes from the input box.
public static List<EmailArticle> findAllEmailArticlesByHeadlineOrSummaryOrImplication(String searchText) {
Query query = entityManager().createQuery(QUERY_FIND_BY_SEARCH_TEXT, EmailArticle.class);
String searchTextUpperCase = "%" + searchText.toUpperCase() + "%";
query.setParameter("headline", searchTextUpperCase);
query.setParameter("implication", searchTextUpperCase);
query.setParameter("summary", searchTextUpperCase);
List<EmailArticle> emailArticles = query.getResultList();
return emailArticles;
}
So I would like to bring back all results for alzheimer's regardless of weather their is an apostrophe or not. I think I have given enough information but if you need more just say. Not really sure where to go with it or how to do it, is it possible to just replace/remove all punctuation or just apostrophes from a user search?
In my point of view, you should change your query,
you should add alter your table and add a FULLTEXT index to your columns (headline, implication, summary).
You should also use MATCH-AGAINST rather than using LIKE query and most important, read about SOUNDEX() syntax, very beautiful syntax.
All I can give you is a native query example:
SELECT o.* FROM email_article o WHERE MATCH(o.headline, o.implication, o.summary) AGAINST('your-text') OR SOUNDEX(o.headline) LIKE SOUNDEX('your-text') OR SOUNDEX(o.implication) LIKE SOUNDEX('your-text') OR SOUNDEX(o.summary) LIKE SOUNDEX('your-text') ;
Though it won't give you results like Google search but it works to some extent. Let me know what you think.

SQL Select Like Keywords in Any Order

I am building a Search function for a shopping cart site, which queries a SQL Server database. When the user enters "Hula Hoops" in the search box, I want results for all records containing both "Hula" and "Hoop", in any order. Furthermore, I need to search multiple columns (i.e. ProductName, Description, ShortName, MaufacturerName, etc.)
All of these product names should be returned, when searching for "Hula hoop":
Hula hoop
Hoop Hula
The Hoopity of xxhula sticks
(Bonus points if these can be ordered by relevance!)
It sounds like you're really looking for full-text search, especially since you want to weight the words.
In order to use LIKE, you'll have to use multiple expressions (one per word, per column), which means dynamic SQL. I don't know which language you're using, so I can't provide an example, but you'll have to produce a statement that's like this:
For "Hula Hoops":
where (ProductName like '%hula%' or ProductName like '%hoops%')
and (Description like '%hula%' or Description like '%hoops%')
and (ShortName like '%hula%' or ShortName like '%hoops%')
etc.
Unfortunately, that's really the only way to do it. Using Full Text Search would allow you to reduce your criteria to one per column, but you'll still have to specify the columns explicitly.
Since you're using SQL Server, I'm going to hazard a guess that this is a C# question. You'd have to do something like this (assuming you're constructing the SqlCommand or DbCommand object yourself; if you're using an ORM, all bets are off and you probably wouldn't be asking this anyway):
SqlCommand command = new SqlCommand();
int paramCount = 0;
string searchTerms = "Hula Hoops";
string commandPrefix = #"select *
from Products";
StringBuilder whereBuilder = new StringBuilder();
foreach(string term in searchTerms.Split(' '))
{
if(whereBuilder.Length == 0)
{
whereBuilder.Append(" where ");
}
else
{
whereBuilder.Append(" and ");
}
paramCount++;
SqlParameter param = new SqlParameter(string.Format("param{0}",paramCount), "%" + term + "%");
command.Parameters.Add(param);
whereBuilder.AppendFormat("(ProductName like #param{0} or Description like #param{0} or ShortName like #param{0})",paramCount);
}
command.CommandText = commandPrefix + whereBuilder.ToString();
SQL Server Full Text Search should help you out. You will basically create indexes on the columns you want to search. in the where clause of your query you will use the CONTAINS operator and pass it your search input.
you can start HERE or HERE to learn more
You might want to check out SOLR too - if you're going to be doing this type of searching. Super cool.
http://lucene.apache.org/solr/