HQL syntax error : 'NHibernate.Hql.Ast.ANTLR.QuerySyntaxException' - sql

As a beginner in HQL , I have a SQL query that I'm trying to transform into hql.
select * from (
   select *
   from CORRELATION_VUE
   where film = v_oldidfilm and FILM2 not in (
                           select c.idfilm
                           from cotes c
                           where idclient = v_idclient)
   order by CORRELATION desc
 
 )
 where rownum <= 3;
So in HQL I'm trying this :
ISession s = NHibernateHelper.GetCurrentSession();
ITransaction tx = s.BeginTransaction();
IQuery query = s.CreateQuery(
#"select u from (
select u from vueCorreliser u
where u.film = :idfilm
and u.FILM2 not in (
select c.idfilm from cote c
where c.idclient = :idclient)
order by u.CORRELATION desc)
where rownum <= 3; ")
.SetInt32("idfilm", idfilm)
.SetInt32("idclient", idclient);
IList<Film> result = query.List<Film>();
tx.Commit();
return result;
But I'm receiving a syntax error on the CreateQuery line.
What did I do wrong?
Thank you

Though I consider this a duplicate of this other question from you, here is a separate, more explicit answer here.
hql does not support sub-queries in from statement. (It supports them in other statements, such as in where conditions.) You have to rewrite your query without the sub-query in the from.
Your sub-query seems to be there only for limiting rows count. Remove the row limit from the query, and use .SetMaxResults(yourMaxRowCount) on the HQL query object instead.
There are no needs for the termination statement ; in HQL, and I do not know if it is supported. I think it is not, better remove it.
var query = s.CreateQuery(
#"select u from vueCorreliser u
where u.film = :idfilm
and u.FILM2 not in (
select c.idfilm from cote c
where c.idclient = :idclient)
order by u.CORRELATION desc")
.SetInt32("idfilm", idfilm)
.SetInt32("idclient", idclient)
.SetMaxResults(4);
That should fix the QuerySyntaxException.
By the way, your usage pattern of transaction is not safe. When using locally scoped transactions, always nest them in using for ensuring they are properly closed.
using (var tx = session.BeginTransaction())
{
...
tx.Commit();
return result;
}
Even in case of failure, the transaction will then always be disposed, which causes it to rollback if it were still ongoing.

Related

Entity framework join with a subquery via linq syntax

I'm trying to translate a sql query in linq sintax, but I'm having big trouble
This is my query in SQL
select * FROM dbo.ITEM item inner join
(
select SUM([QTA_PRIMARY]) QtaTotale,
TRADE_NUM,
ORDER_NUM,
ITEM_NUM
from [dbo].[LOTTI]
where FLAG_ATTIVO=1
group by [TRADE_NUM],[ORDER_NUM],[ITEM_NUM]
)
TotQtaLottiGroupByToi
on item.TRADE_NUM = TotQtaLottiGroupByToi.TRADE_NUM
and item.ORDER_NUM = TotQtaLottiGroupByToi.ORDER_NUM
and item.ITEM_NUM = TotQtaLottiGroupByToi.ITEM_NUM
where item.PRIMARY_QTA > TotQtaLottiGroupByToi.QtaTotale
and item.FLAG_ATTIVO=1
How can I translate into linq sintax?
This approach doesn't work
var res= from i in context.ITEM
join d in
(
from l in context.LOTTI
group l by new { l.TRADE_NUM, l.ORDER_NUM, l.ITEM_NUM } into g
select new TotQtaByTOI()
{
TradeNum = g.Key.TRADE_NUM,
OrderNum = g.Key.ORDER_NUM,
ItemNum = g.Key.ITEM_NUM,
QtaTotale = g.Sum(oi => oi.QTA_PRIMARY)
}
)
on new { i.TRADE_NUM, i.ORDER_NUM, i.ITEM_NUM} equals new { d.TradeNum, d.OrderNum, d.ItemNum }
I get this error
The type of one of the expressions in the join cluase is incorrect. Type inference failed in the call to 'Join'
Can you help me with this query?
Thank you!
The problem is Anonymous Type comparison. You need to specify matching property names for your two anonymous type's properties (e.g. first, second, third)
I tried it out, here's an example: http://pastebin.com/hRj0CMzs

How to get the latest/last record with a group by clause with NHibernate Linq provider

I have used too much time (days) on this and I really hope someone can help me out.
I found a good article on describing my problem in a generic way so let's stick to it.
I am trying to build this query but NHibernate fails to build the correct sql and returns a sql query exception.
Column vSagsAendring.Id is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. It could not execute the following query:
select
viewsagsae0_.Id as Id155_,
viewsagsae0_.SagId as SagId155_,
viewsagsae0_.JournalNr as JournalNr155_,
viewsagsae0_.LbfNr as LbfNr155_,
viewsagsae0_.OrgNr as OrgNr155_,
viewsagsae0_.OrgNavn as OrgNavn155_,
viewsagsae0_.AfdNavn as AfdNavn155_,
viewsagsae0_.SagsType as SagsType155_,
viewsagsae0_.Status as Status155_,
viewsagsae0_.SagsbehandlerInit as Sagsbeh10_155_,
viewsagsae0_.Dato as Dato155_,
viewsagsae0_.JournalAktionType as Journal12_155_,
viewsagsae0_.Beskrivelse as Beskriv13_155_,
viewsagsae0_.Ekstern as Ekstern155_
from vSagsAendring viewsagsae0_
group by viewsagsae0_.SagId
var query = from p in _session.Query<ViewSagsAendring>()
group p by p.SagId
into grp
select grp.OrderByDescending(g => g.Dato).First();
This is another version also took from the article:
var query = from p in _session.Query<ViewSagsAendring>()
group p by p.SagId
into grp
let maxDato = grp.Max(g => g.Dato)
from p in grp
where p.Dato == maxDato
select p;
It's have been a long journey, but now it's over. I hope that I can help someone else in the same situation by answering my own question.
var aendring = from sagsAendring in _session.Query<ViewSagsAendring>()
where sagsAendring.Dato ==
(
from innersagsAendring in _session.Query<ViewSagsAendring>()
where innersagsAendring.SagId == sagsAendring.SagId
select innersagsAendring.Dato
).Max()
select sagsAendring;
var result = aendring.ToList();
And because you can chain linq statements you can build a linq filter like this
if(Filters.VisInterneAendringer == false)
query = query.Where(x => x.Ekstern == true);
if (Filters.VisKunNyesteAendringer)
{
query = query.Where(sagsAendring => sagsAendring.Dato ==
(
from innerSagsAendring in Session.Query<ViewSagsAendring>() where innerSagsAendring.SagId == sagsAendring.SagId
select innerSagsAendring.Dato
).Max());
}
return query;
Your queries seem legit for LINQ in EntityFramework.
I'm not sure about hibernate, you might try to use QueryOver API instead of Query
http://nhibernate.info/blog/2009/12/17/queryover-in-nh-3-0.html

Entity Framework, why is this sql being generated?

When I look at the SQL query generated by EF I see
SELECT [extent1].ID as ID,
[extent1].Name as Name
From(
Select myview.ID as ID,
myview.Name as Name
From myview) AS [extent1]
Where([Extent1].ID = #p_linq_0)
Why is the outside select happening on the inside select? I've got a very large table that I can get a record from easily with the outside query but the whole query combined times out.
My Linq query
var result = from i in invitationEntity.Invitations
.Where(a=>a.id == inviationId)
select i;
I am using SQL 2012 & EF5 & Linq.
Is there a way to "force" the simpler query?
Because you are calling "SELECT" once again at the end along with LINQ method.
var result = from i in invitationEntity.Invitations
.Where(a=>a.id == inviationId)
select i;
The last line select i, is useless, but EF is not aware of it whether it has anything useful or not, you can simply avoid it.
var result = invitationEntity.Invitations
.Where(a=>a.id == inviationId);
You can still enumerate result and get everything.
Ok sorry, I forgot to add, you don't have to use "from", you can simply use .Where(expression )
And if you want to use LINQ keywords, then you can use it this way,
var result = from i in invitationEntity.Invitations
where i.id == invitationId
select i;
You cannot mix LINQ keywords and LINQ extension methods.
i would say that
var result = from i in invitationEntity.Invitations
.Where(a=>a.id == inviationId)
select i;
this
a=>a.id == inviationId
from a=> generate
Select myview.ID as ID,
myview.Name as Name
From myview
so a is [extent1]
you should use a "standard" where clause
from i in invitationEntity.Invitations
where i.id == inviationId
select i;

HQL size using QueryOver without subquery

Hope that someone can answer this.
I know that I can do the following using hql (pseudo code below)
var hql = "from objectA l where size(l.ChildCollection) > 0";
var data = Session.CreateQuery(hql)
.List<objectA>();
Is there a wondering if you could do something similar using QueryOver. Without resorting to using a sub query.I have a session filter on ChildCollection.
Unfortunately,
var query = QueryOver.Of<ObjectA>()
.WhereRestrictionOn(x => x.ChildCollection).IsNotEmpty();
Produces,
WHERE
exists(
select
1
from
[ChildCollection]
where
this_.Id=ObjectA_Id
);
Where as the Hql produces,
where
(
select
count(childcollection1_.ObjectA_Id)
from
[ChildCollection] childcollection1_
where
objectA0_.Id=childcollection1_.ObjectA_Id
and childcollection1_.DTCreated between #p0 and #p1
)>0
Cheers
Tanzy
var query = QueryOver.Of<ObjectA>().WhereRestrictionOn(x => x.ChildCollection).IsNotEmpty();
Both queries will generate similar sql:
SELECT this_.Id
FROM [ObjectA] this_
WHERE exists(select 1 from [ChildObjectB] where this_.Id = [key])
Is this what you were trying to achieve?

How to execute query with subqueries on a table and get a Rowset object as a result in Zend?

I'm currently struggling on how to execute my query on a Table object in Zend and get a Rowset in return. Reason I need particularly THIS is because I'm modifying a code for existing project and I don't have much flexibility.
Query:
SELECT *
FROM `tblname` ud
WHERE ud.user_id = some_id
AND
(
(ud.reputation_level > 1)
OR
(
(SELECT COUNT( * )
FROM `tblname` t
WHERE t.user_id = ud.user_id
AND t.category_id <=> ud.category_id
AND t.city_id <=> ud.city_id
) = 1
)
)
Is there a way to describe this query using Select object?
Previous SQL solution was very simple and consisted of one WHERE clause:
$where = $this->getAdapter()->quoteInto("user_id = ?",$user_id);
return $this->fetchAll($where);
I need to produce same type of the result (so that it could be processed by existing code) but for more complicated query.
Things I've tried
$db = Zend_Db_Table::getDefaultAdapter();
return $db->query($sql)->fetchAll();
---------------- OR ----------------------
return $this->fetchAll($select);
---------------- OR ----------------------
return $this->_db->query($sql)->fetchAll();
But they either produce arrays instead of objects or fail with Cardinality violation message.
I would appreciate any help on how to handle SQL text queries in Zend.
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
//change the fetch mode becouse you don't like the array
$dbAdapter->setFetchMode(Zend_Db::FETCH_OBJ);
$sql = "you're long sql here";
$result = $dbAdapter->fetchAll($sql);
Zend_Debug::dump($result);
exit;
For a list of all fetch modes go to Zend_Db_Adapter
To write you're query using Zend_Db_Select instead of manual string , look at Zend_Db_Slect