Different query after nhibernate 5 (using oracle) - nhibernate

After upgrading from 4.1 to 5.2, nhibernate is creating a query a little different, putting an "OR" where it is not welcome.
4.1
...,
...,
(select cast(count(guia5_.ID) as NUMBER(10, 0))
from SAM_GUIA guia5_
where guia5_.PEGID = peg1_.ID <<<<<<<<<<<<<<<
) as col_41_0_,
5.x
...,
...,
(select cast(count(guia5_.ID) as NUMBER(10, 0))
from SAM_GUIA guia5_
where guia5_.PEGID = peg1_.ID <<<<<<<<<<<<<<<
or (guia5_.PEGID is null) <<<<<<<<<<<<<<<
and (peg1_.ID is null) <<<<<<<<<<<<<<<
) as col_41_0_,
The linq query related is:
...,
...,
RecordCount = (from c in repositoryGuia.All()
where c.PegId == b.Id
select c.Id
).Count(),
More information about mapping:
c.PegId: int?
b.Id: int
Using NHibernate 5.2.6 and Fluent 2.1.2.
Why version 5 is translating to a different SQL statement?

It's a known 5.x issue GH-1860. Details when and why behavior is changed explained here.
AFAIK there is no workaround for LINQ so you have to use hql/QueryOver if it's a showstopper for you.
But there is an open pull request here that should fix this behavior. So maybe in 5.3 it will be fixed.

Related

Jetbrains Exposed SQL HAVING COUNT(*)

I need to achieve this next SQL query using the Exposed framework from Jetbrains
select r.name
from recipes r
inner join ingredient_index i on i.recipe_id = r.recipe_id
where i.ingredient_id IN (7, 5)
GROUP BY r.name
HAVING COUNT(*) = 2
This is taken directly from this answer, and the result from the query in native SQL is exactly what I'm looking for, but I'm using Exposed framework on my backend.
Stackoverflow question
I'm having issues with the last part HAVING COUNT(*) = X
I see there's a method I can use that's query.having { } but I don't see how I could implement the COUNT(*) = X inside that expression.
Any help is appreciated.

Select all entries that have multiple associated versions

Basically I want a select statement that selects ID, and Version, but each ID has multiple versions, so I want to select all ID's in the table and each version associated with each ID.
If I just do:
select ID, Version FROM Table
then I only get an ID and it's associated most recent version, I don't get multiple entries for ID=X and the multiple versions associated with ID X, etc
Example of data I want:
ID = 1, Version = 0
ID = 1, Version = 1.0
ID = 1, Version = 2.0
ID = 2, Version = 0
ID = 2, Version = 1.0
ID = 2, Version = 2.0
ID = 2, Version = 3.0
ID = 3, Version = 0
ID = 4, Version = 0
ID = 4, Version = 1.0
etc etc
If your table structure include 2 columns ID (see Note) and version AND a row existed for every combination of row/version then SELECT ID, version would list all the rows.
e.g. CREATE TABLE IF NOT EXISTS details (id INTEGER, version TEXT);
And it is populated as follows :-
Then the result of SELECT id,version from details; would be :-
Or if the query were SELECT 'ID= ' ||id||', Version= ' || version AS vercol FROM details; it would be (to cater for how you have shown you want the result) :-
Note where the column named id is not an alias of rowid (i.e it is not defined as id INTEGER PRIMARY KEY or id INTEGER PRIMARY KEY AUTOINCREMENT).
However
If the structure and usage is not based upon the above then you will likely encounter issues.
For example the following stores the latest version (and other versions) :-
Then SELECT id, version FROM details_alt; would result in what you appear to be describing i.e (the otherversion columns are ignored in this usage):-
To manipulate such a structure and either calculating the other than highest versions or including other columns would be quite complex. For example this is part way towards doing the former :-
SELECT
CASE
WHEN version < 1 THEN 'ID= '||id||', Version=0'
WHEN version < 2 THEN 'ID= '||id||' Version=0, 1.0'
WHEN version < 3 THEN 'ID= '||id||' Version=0, 1.0, 2.0'
WHEN version < 4 THEN 'ID= '||id||' Version=0, 1.0, 2.0, 3.0'
END AS idcol
FROM details_alt
and would result in :-
In short if your table isn't structured as initially shown, which it would appear to be the case, you are introducing unnecessary complexity and are not following well established database design techniques.
The answer, again if not using the initial structure, is to utilise a design along the lines of the initial design shown.
Otherwise you should amend your question to show the table's structure and how it is utilised when storing with an example of actual data.
It's as simple as
SELECT ID , Version FROM Table WHERE ID='X'
Here X is your ID number
honestly, your question is kinda confusing because
select ID, Version From table
would bring all data from table, I think the table is big and thats why it looks like it doesnt show all Versions for each id, So Try using an Order by .
select ID, Version FROM Table
order by ID, Version

Core Data SUBQUERY with key-path collection causes SQL error

I'm experiencing a SQL error from a Core Data-generated query. Here's the data model:
I want to get all of the drivers for whose busses have active passengers. This is simply described by the following fetch request and predicate, which works:
NSFetchRequest(entityName: "Driver")
NSPredicate(format: "ANY bus.passengers.active == YES")
However, let's say I want to do a more complex query on the passenger, like they are both active and a balance above 100. To do such a query, I'd have to use a SUBQUERY, like so:
NSPredicate(format: "SUBQUERY(bus.passengers, $passenger, $passenger.active == YES
AND $passenger.balance > 100).#count > 0")
I would expect SUBQUERY to accept a keypathed collection as its first argument. It generates the following SQL query:
SELECT 0,
t0.z_pk,
t0.z_opt,
t0.zbus
FROM zdriver t0
WHERE (SELECT Count(t2.z_3passengers)
FROM zbus t1
JOIN z_1passengers t2
ON t1.z_pk = t2.z_1busses
WHERE ( t0.zbus = t1.z_pk
AND (( t2.zactive = ?
AND t2.zbalance > ? )) )) > ?
And the error: 'no such column: t2.ZACTIVE'. It looks like it's missing a JOIN on the ZPASSENGER table.
Is this a Core Data bug or is there a different way to write this predicate?
Update: Here's a sample project that reproduces this issue.
Try fetching the Bus entity, avoiding the key path in the first argument in the SUBQUERY.
As was pointed out, this can be viewed as a limitation or a bug.
Update:
Further research suggests that your subquery predicate should actually work. I would recommend to check your NSManagedObject subclasses and make sure passengers returns a collection and active is properly listed as an attribute.

Right Join in Doctrine2 for Symfony2

I have the following working MySQL query:
SELECT *
FROM bogenantworten a
RIGHT JOIN
bogenfragen f ON f.id = a.bogenfragen_id
AND a.personen_id = 3,
BogenTyp t,
BogenFragenGruppe g
WHERE
t.id = f.fragentyp_id AND
g.id = f.fragengruppen_id AND
t.id = 1
ORDER BY f.sortierung ASC
Now I need this in Doctrine2 DQL or QueryBuilder. I already learned that D2 is forcing me to think in objects, but I couldn't find any advice how to tag my entities to make this work.
So I'd like to either have the above MySQL query working in my Symfony2 app or some help how to annotate my entities right so I have a working right join connection between BogenAntworten and BogenFragen (the 3 and the 1 are parameters, just so you know). I already set the OneToMany and ManyToOne annotations for all my entities, but I need something to make a right/left join working.
If you want to help me with my entity design:
I have persons (table Person) who answers (table BogenAntworten) questions (table BogenFragen), and when I show the list of questions I either get the last answer from that question (need UPDATE when saving) or there is none and I have to create it (INSERT when saving). Questions also are in one of many types (table BogenTyp) and are in one of many groups (table BogenFragenGruppe)
Any Ideas?
OK, found it out myself again. The QueryBuilder of Doctrine2 supports a leftJoin (which is identical to the RIGHT JOIN if you switch the two tables). For those need some code, here is the above SQL statement build with QueryBuilder:
$query = $em->createQueryBuilder()
->select(array('f.id', 'f.frage', 'f.sortierung', 'a.antwort', 'g.name'))
->from('MySuperBundle:BogenFragen', 'f')
->leftJoin('f.bogenantworten', 'a', 'WITH', 'a.personen = :pid')
->from('MySuperBundle:BogenTyp', 't')
->from('MySuperBundle:BogenFragenGruppe', 'g')
->where('t.id = :tid')
->andWhere('t.id = f.bogentypen')
->andWhere('g.id = f.bogenfragengruppe')
->orderBy('f.sortierung', 'ASC')
->setParameter('tid', 1)
->setParameter('pid', 3)
->getQuery();
(The parameters are actually dynamic, but for easier reading I used the numbers of the original SQL statement)

NHibernate - ICriteria for two tables?

I'm having a heck of a time creating the ICriteria for two tables.
The SQL I am trying to mimic is below.
Is there anyway to do this?
I've been trying CreateAlias, Subqueries, and a bunch of other stuff But I always end up with errors.
I have tried posting this on the nhusers Google group, but not getting much help.
Thanks.
Kim
SELECT *
FROM Echo_File_status efs, Data_DELETION_PARAMETER ddp
WHERE
efs.EFS_PRODUCT_CODE = DDP.DDP_PRODUCT_CODE(+)
AND
DDP.DDP_PROCESS_TYPE = 'D'
AND
( ( trunc(nvl(efs.efs_file_create_date, sysdate)) > sysdate - dp.DDP_DAYS_ON_LINE ) or
( efs.efs_status_code != 'ACKED' ) )
ORDER BY efs.efs_product_code, decode(efs.efs_status_code, 'READY', 1, 'TRANS', 2 , 'FAERR', 3, 'FCERR', 4, 'PRERR', 5, 'TRERR', 6, 'PREP', 7, 'PRCOM', 8, 'FCREA', 9 , 'TRCOM', 10, 'ACKED', 11, 1),
efs.efs_file_create_date DESC
Why use icriteria while Hql would be easy to use? Join the objects on that code property.
My personal opinion on this kind of problem, is that you should just keep writing expressions like that in pure SQL, since it will only be worse to read and maintain using the NHibernate criteria API.
As long as you have test coverage on the query, you can safely hide that implementation detail away.