NHibernate RowCount in LINQ produces SQL Exception - sql

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();

Related

WHERE clause returning no results

I have the following query:
SELECT *
FROM public."Matches"
WHERE 'Matches.Id' = '24e81894-2f1e-4654-bf50-b75e584ed3eb'
I'm certain there is an existing match with this Id (tried it on other Ids as well), but it returns 0 rows. I'm new to querying with PgAdmin so it's probably just a simple error, but I've read the docs up and down and can't seem to find why this is returning nothing.
Single quotes are only used for strings in SQL. So 'Matches.Id' is a string constant and obviously not the same as '24e81894-2f1e-4654-bf50-b75e584ed3eb' thus the WHERE condition is always false (it's like writing where 1 = 0)
You need to use double quotes for identifiers, the same way you did in the FROM clause.
WHERE "Matches"."Id" = ...
In general the use of quoted identifiers is strongly discouraged.

How to add one more column in the select using Laravel Eloquent

I am trying to use Laravel Eloquent to make a query. I would like to group the results by the level column, count the results in a total alias, and finally, bring me the id of each result. What am I doing wrong?
$fodas = Foda::groupBy('level')
->select('level', DB::raw('count (*) as total'))
->get();
The result is a collection that only brings me the level and total fields.
You'll see this pattern with many laravel facades. If you are handling 'one of something', in this case a column, you pass a string and if you are handling many of something, you pass an array.
That's why * and level are both valid. Because * is recognized a column and is expanded inside mysql to match every column.
And that's also why it doesn't work when you try to query for 'level, column2, column3' because this string is not a valid column name, so you have to pass an array with all the columns you want to use.
$fodas = Foda::groupBy('level')
->select(['level','other','column'], DB::raw('count (*) as total'))
->get();
As I said before, this applies to many laravel facades:
Facade::function('one_thing');
//or
Facade::function(['thing1','thing2','thing3']);
//or even this, for some cases
Facade::function('thing1','thing2','thing3');

Linq Optional Where String

SQL IN STOR:
select * from Car_Company where (#id is null or ID=#id)
What is the code corresponding to the next line ( In Linq )
From A IN DB.Company Where (IIF(String.IsNullOrEmpty(TextBox1.Text),a.cNAME=TextBox1.Text)).ToList
I would recommend pulling your string evaluation out of the LINQ statement and evaluating it once then using the evaluated value in your query. Also, if the value is supposed to be a number, but you can't guarantee if the user supplied a number, you need to test it first to make sure that you have a number in order to avoid the casting issue. The LINQ query that you supplied doesn't quite make sense because the where clause returns a string not a true/false result. You need to compare the value with something in the data rows. I think you want something like:
Dim Id As Integer
If Integer.TryParse(TextBox1.Text, Id) Then
Dim Query = From A IN DB.Company Where A.Id = Id
End If
It's totally unclear... Try this...
(From A IN DB.Company Where IF(Not String.IsNullOrEmpty(TextBox1.Text),
A.cNAME=TextBox1.Text,
"Something else")).ToList

HQL Date throwing unexpected token

Hi I have trouble executing the following query in HQL:
This is a very dangerous approach to running queries. It's the sort of thing that creates SQL injection risks. Never concatenate values into SQL or HQL strings like that. Always use the PreparedStatement approach of using placeholders in the SQL/HQL string and setting the values programmatically. This way the driver (and Hibernate in the case of HQL) can do the correct thing with the SQL that gets generated. Of course here the value is a date and not a user-submitted string, but the principle still holds.
What you need to do is run a query more like
'select stuff from bar b where b.dateCreated = ?'
In HQL you can also use named parameters, and those are usually a lot easier to read and self-documenting, e.g.
'select stuff from bar b where b.dateCreated = :date'
Then set the value as part of the call, not with string concatenation.
The problem here is that the Java/Groovy toString value of a date is nothing at all like what the date format should be in SQL (or HQL). Luckily you don't need to know what that format should be, because the JDBC driver does.
So your query should be
def co = Bid.executeQuery(
'select b.job from Bid b left join b.job j where j.dateCreated = :date',
[date: fromDates[i])
Here I'm using the name date but that's arbitrary, is just has to match the key name in the map with values. You can also use SQL-style ? chars and a list of values:
def co = Bid.executeQuery(
'select b.job from Bid b left join b.job j where j.dateCreated = ?',
[fromDates[i])
Once you get this working you'll find that comparing dates like this rarely works because the dates have to agree to the millisecond, but that's a problem for another question :)

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")