Could you do a query with subqueries like this with nhibernate? - sql

If you had a query that looks like this, could it be converted into a nhibernate query?
SELECT ....
FROM
(
SELECT ...
FROM ...
GROUP BY...
ORDER BY ...
UNION
SELECT ..
FROM ...
)
AS ASDF
GROUP BY ...
ORDER BY ...

With hibernate you can do native SQL queries. You just need to create a named Sql query mapping, and map it to a class.
However, you will not get the benefit of writing to the named query. [Which is to be expected]

if by "nhibernate query" you mean to use any non-sql method to express an sql query, like using HQL or the ICriteria api, no you wouldn't be able to use the union or to express a result set using select * FROM ( select ... ) as FOO
The named query that monksy refers to is writing an SQL-query that you bind to the mapping but you cannot manipulate that query in many ways

Related

Nhibernate queryover union

I have two queries based in session.QueryOver. The queries are different, but returns a IList the same type object.
The number of result of the two query, is the total object that i need.
How can I combine both queryover?
Is possible to do a union in NHibernate?
You could consider using CreateSQLQuery instead. Form your SQL query syntax with the UNION keyword and use CreateSQLQuery to execute your query and get your result.
ISessionFactory.OpenSession().CreateSQLQuery("SELECT * FROM A UNION SELECT * FROM B")
.SetResultTransformer(Transformers.AliasToBean(typeof(YourClass)))
.List<YourClass>();

HQL Subquery Problems

I'm getting a HQL error every time I try to run this subquery. This type of query should work in SQL right? How is HQL handling this type of query differently?
SELECT *
FROM Table
WHERE user_Id IN (
SELECT a.user_Id
FROM Table a
WHERE a.color='Blue')
It looks like HQL does not support IN?
I'm getting a error: "Cannot recognize input near 'SELECT'"
In hql if you want to select all fields, you have two ways:
1-You can remove select clause like:
FROM Table
WHERE user_Id IN (
SELECT a.user_Id
FROM Table a
WHERE a.color='Blue')
or
2-If you want to use select clause, you must use an alias:
SELECT t
FROM Table t
WHERE t.user_Id IN (
SELECT a.user_Id
FROM Table a
WHERE a.color='Blue')
It looks like your syntax is incorrect. Try this:
SELECT *
FROM Table
WHERE user_Id IN (
SELECT a.user_Id
FROM Table a
WHERE a.color='Blue')
There is no "*" in HQL. Only alias should be present.
SELECT t
FROM Table t
HQL supports "In".
Also, make sure, the java class field name is "user_Id". You may be using the DB column name here.

HQL count from multiple tables

I would like to query my database using a HQL query to retrieve the total number of rows having a MY_DATE greater than SOME_DATE.
So far, I have come up with a native Oracle query to get that result, but I am stuck when writing in HQL:
SELECT
(
SELECT COUNT(MY_DATE)
FROM Table1
WHERE MY_DATE >= TO_DATE('2011-09-07','yyyy-MM-dd')
)
+
(
SELECT COUNT(MY_DATE)
FROM Table2
WHERE MY_DATE >= TO_DATE('2011-09-07','yyyy-MM-dd')
)
AS total
I actually have more than 2 tables but I keep having an IllegalArgumentException (unexpected end of subtree).
The working native Oracle basically ends with FROM dual.
What HQL query should I use to get the total number of rows I want?
First of, if you have a working SQL query, why not just use that instead of trying to translate it to HQL? Since you're returning a single scalar in the first place, it's not like you need anything HQL provides (e.g. dependent entities, etc...)
Secondly, do you have 'dual' mapped in Hibernate? :-) If not, how exactly are you planning on translating that?
That said, "unexpected end of subtree" error is usually caused by idiosyncrasies of Hibernate's AST parser. A commonly used workaround is to prefix the expression with '0 +':
select 0 + (
... nested select #1 ...
) + (
... nested select #2 ...
) as total
from <from what exactly?>

How to refer to a variable create in the course of executing a query in T-SQL, in the WHERE clause?

What the title says, really.
If I SELECT [statement] AS whatever, why can't I refer to the whatever column in the body of the WHERE clause? Is there some kind of a workaround? It's driving me crazy.
As far as I'm aware, you can't directly do this in SQL Server.
If you REALLY have to use your column alias in the WHERE clause, you can do this, but it seems like overkill to use a subquery just for the alias:
SELECT *
FROM
(
SELECT [YourColumn] AS YourAlias, etc...
FROM Whatever
) YourSubquery
WHERE YourAlias > 2
You're almost certainly better off just using the contents of the original column in your WHERE clause.
It has to do with the way a SELECT statement gets translated into an abstract query tree: the 'whatever' only appears in the query result projection part of the tree, which is above the filtering part of the tree, so the WHERE clause cannot understand the 'whatever'. This is not some internal implementation detail, it is a fundamental behavior of relational queries: the projection of the result occurs after the evaluation of the joins and filters.
IS really trivial to work around the 'problem' by making the hierarchy of the query explicit:
select ...
from (
select [something] as whatever
from ...
) as subquery
WHERE whatever = ...;
A common table expression can also server the same purpose:
with cte as (
select [something] as whatever
from ...)
select ... from cte
WHERE whatever = ...;
It's to do with the order of operations in the select statement. The WHERE clause is evaluated before the SELECT clause so this information isn't available. Although it is available in the ORDER BY clause as this is processed last.
As others have mentioned, a sub-query will get around this problem.

NHibernate use Criteria for Count(),First()

I have a question about Criteria method, one-to-many relation to the database, 'one' is "account", 'many' is "sites", when I use CreateCriteria() something is not right.
Like this: SessionFactory.OpenSession().CreateCriteria(typeof(Account)).List().Count();
Before it's run, I think the SQL should be SELECT COUNT(*) FROM table, but the SQL is SELECT id, siteurl...FROM table. So what's wrong with this? How can I solve it?
And First() method should be SELECT TOP1 ...FROM table, but it is SELECT ...FROM table
I'm an Nhiberate rookie, Please help me.
This happens because the Count method you are calling at the end executes after the query has run and outside of the database. You are only counting the elements in the list in memory. To achieve what you are looking for you could use a projection:
var count = session
.CreateCriteria<Account>()
.SetProjection(
Projections.Count(Projections.Id())
)
.UniqueResult<long>();