How to Search substring in Multiple columns using Hibernate - sql

following is my code to call the database to find the substring "ello".
String queryString = "from ContentItem where singerName = '%"+searchString+"%' OR songName = '%"+searchString+"%'";
System.out.println(queryString);
Query query = session.createQuery(queryString);
return query.list();
the string output is
from ContentItem where singerName = '%ello%' OR songName = '%ello%'
it says Unexpected Token for %. How to make this possible to search substring inside those columns?
I'm working Hibernate inside Tapestry.

the equals (=) operator does not work with wildcards. You need to use like (or ilike).
eg
SELECT * FROM table WHERE column like '%abc%';
see this document for more info.

Related

Access 10 sql query

I want to use LIKE operator in access 10 sql query with variable.
Example:
temporary variable var contains value bs
var = "bs"
I want to match every String that starts with value of temporary variable followed by zero or more numbers.
I am trying to fire the query:
select * from xyz where variety LIKE "#[tempvars]![var] + [0-9]*"
It is returning 0 records.
Thankz for the help.
You need to refer to your tempvar outside of the quotes, and use & for concatenation:
select * from xyz where variety LIKE "#" & [tempvars]![var] & "[0-9]*"
This will return all records where variety starts with a literal #, then whatever is in [tempvars]![var], then a number, and then any amount of characters.
You can check if that variety is available in your table or not. If that variety is available in your table then don't search with like operator and otherwise use like operator.

sqlite text data type comparison not working

I have a table in SQLite database with data type text, but when I do comparison its not working if I do it this way :
select * from scanned_dbs where db = 'cdd_db';
But if i change the query to:
select * from scanned_dbs where db like 'cdd_db';
It works. But as valex pointed out it will also match cddAdb, cddBdb, ...and so on, so this is not the right way.
One more method I found which is working is this:
select * from scanned_dbs where cast(db as varchar) = 'cdd_db';
So can any one tell me why this is working and not the first one which is direct comparison...
Because an underscore ("_") in the LIKE pattern matches any single character in the string.
So when you use db = 'cdd_db' the only db value that matches is exact 'cdd_db'. But when you use the LIKE operator db like 'cdd_db' then "_" symbol is a pattern so db values that match: cddAdb,cddBdb,cddcdb,cddddb,cdd1db, ....

Implement an IN Query using XQuery in MSSQLServer 2005

I'm trying to query an xml column using an IN expression. I have not found a native XQuery way of doing such a query so I have tried two work-arounds:
Implement the IN query as a concatenation of ORs like this:
WHERE Data.exist('/Document/ParentKTMNode[text() = sql:variable("#Param1368320145") or
text() = sql:variable("#Param2043685301") or ...
Implement the IN query with the String fn:contains(...) method like this:
WHERE Data.exist('/Document/Field2[fn:contains(sql:variable("#Param1412022317"), .)]') = 1
Where the given parameter is a (long) string with the values separated by "|"
The problem is that Version 1. doesn't work for more than about 50 arguments. The server throws an out of memory exception. Version 2. works, but is very, very slow.
Has anyone a 3. idea? To phrase the problem more complete: Given a list of values, of any sql native type, select all rows whose xml column has one of the given values at a specific field in the xml.
Try to insert all your parameters in a table and query using sql:column clause:
SELECT Mytable.Column FROM MyTable
CROSS JOIN (SELECT '#Param1' T UNION ALL SELECT '#Param2') B
WHERE Data.exist('/Document/ParentKTMNode[text() = sql:column("T")

NHibernate RowCount in LINQ produces SQL Exception

I have a query where I am only interested in the row count, however the query that NHibernate produces does not work with Sybase. I already have a custom Sybase dialect, but I can't find where to override the rowcount.
Given the following code:
var a = from b in table where b.something = 5 select b
var rows = a.Count
Generates an SQL similar to this:
select cast(count(*) as INTEGER) as p1 from table
I don't get why NHibernate wants to cast the count result, nor how I can override the dialect or elsewhere so NHibernate doesn't include the cast. The result of a count is castable to integer anyways.
If I however use QueryOver, things work perfectly. The problem then however, is that one off my conditions is dependent on the length of a string (yes, the db design could be better, but I can currently not change it). Using linq to call .Length on a string in the conditions work. However I can't use the string length as a condition in the QueryOver expressions. I also need a contains operation, which works with linq, but not QueryOver.
Is there a way to override how the Count query is generated, so it will work?
I am only interested if there is any rows matching, not the count, is there a different way of doing that?
Can instead the QueryOver? interface to use the SQL length and in operators?
You can understand if there are any rows matching by using Any function like this:
var a = from b in table where b.something = 5 select b;
var isMatch = a.Any();

Is there a more efficient way to handle these replace calls

I'm querying across two dbs separated by a legacy application. When the app encounters characters like, 'ü', '’', 'ó' they are replaced by a '?'.
So to match messages, I've been using a bunch of 'replace' calls like so:
(replace(replace(replace(replace(replace(replace(lower(substring([Content],1,153)) , '’', '?'),'ü','?'),'ó','?'), 'é','?'),'á','?'), 'ñ','?'))
Over a couple thousand records, this can (as you expect) is very slow. There is probably a better way to do this. Thanks for telling me what it is.
One thing you can do is implement a RegEx Replace function as a SQL assembly and call is as a user-defined function on your column instead of the Replace() calls. Could be faster. You also want to probably to the same RegEx Replace on your passed in query values.
TSQL Regular Expression
You could create a persisted computed column on the same table where the [Content] column is.
Alternatively, you can probably speed up the replace by creating a user defined function in C# using a StringBuilder. And you can even combine both of these solutions.
[SqlFunction(IsDeterministic = true, IsPrecise = true)]
public static SqlString LegacyReplace(SqlString value)
{
if(value.IsNull) return value;
string s = value.Value;
int l = Math.Min(s.Length, 153);
var sb = new StringBuilder(s, 0, l, l);
sb.Replace('’', '?');
sb.Replace('ü', '?');
// etc...
return new SqlString(sb.ToString());
}
Why not first do the same replace (chars to "?") on the string you are searching for in the app side using regular expressions? E.g. your SQL server query that was passed a raw string to search for and used these nested replace() calls will instead be passed a search string already containing "?"s by your app code.
Could you convert the strings to varbinary before comparing? Something like the below:
declare
#Test varbinary (100)
,#Test2 varbinary (100)
select
#Test = convert(varbinary(100),'abcu')
,#Test2 = convert(varbinary(100),'abcü')
select
case
when #Test <> #Test2 then 'NO MATCH'
else 'MATCH'
end