EF Core with GroupBy - column ambiguously defined - oracle

Trying to filter and group by an IQueryable I get an oracle exception "column ambiguously defined".
The code looks as follows:
public class UserRepository{
public IEnumerable<UserDto> GetUsers(UserFilter filter){
IQueryable<User> users = _context.Users;
return filter.Set(users)
.Select(user => new UserDto(){
Id = user.Id,
NoOfTweets = user.NoOfTweets
}
.ToListAsync();
}
}
public class UserFilter : Filter{
public string? Name {get; set;}
public UserGroupBy? GroupBy{get; set;} //Enum
public override IQueryable<Model> Set(IQueryable<Model> models){
IQueryable<User> users = models.Cast<User>();
users = !string.IsNullOrEmpty(Name)
? users.Where(user => user.Name.Equals(Name))
: users;
if(GroupBy.HasValue)
{
users = GroupBy.Value switch{
UserGroupBy.Name => users
.GroupBy(user => new{
user.Name,
user.Birthday
})
.Select(group => new User(){
Name = group.Key.Name,
NoOfTweets = group.Sum(e => e.NoOfTweets)
})
_ => throw new NotImplementedException()
}
}
return base.Set(users); // in base class the list gets paginated
}
}
I guess the error is because of the two selects (in group-by and finally into userGet) but how can I workaround that cleanly?
I hoped that the entity Framework solves this using aliases, but it doesn't.
My Versions:
Oracle.EntityFrameworkCore: 6.21.61
.Net 6
Additional Thoughts
Doing the Group by after the paginate leads to an incorrect result because the wrong list gets paginated.
It seems that the second Select reexecutes the first on so that the group.Sum(...) is called twice

I know nothing about EF Core, but - as far as Oracle is concerned & based on what you said so far, there are (at least) two positions that might raise the error. I'll try to illustrate it on a simple query which selects sum of salaries per each department.
Asterisk points to position which raised the error:
SQL> select deptno, sum(sal)
2 from emp join dept on emp.deptno = dept.deptno
3 group by deptno;
group by deptno
*
ERROR at line 3:
ORA-00918: column ambiguously defined
OK, so let's add table name - in vain, it still doesn't work because column in select column list also misses its source table name:
SQL> select deptno, sum(sal)
2 from emp join dept on emp.deptno = dept.deptno
3 group by dept.deptno;
select deptno, sum(sal)
*
ERROR at line 1:
ORA-00918: column ambiguously defined
Finally, when fixed:
SQL> select dept.deptno, sum(sal)
2 from emp join dept on emp.deptno = dept.deptno
3 group by dept.deptno;
DEPTNO SUM(SAL)
---------- ----------
30 9400
20 10875
10 8750
SQL>
As I said: I can't interpret code you wrote and don't see anything like what I posted, but I hope that these examples might help you find the culprit.

Related

Linq to join 2 tables and use contains for both tables

Ex:join master table with emp table and fetch empname from master table based on Id present in emp table and search if it contains specific string passed as parameter in master or search I'd passed in emp table.. It basically autocomplete search where u can search based on Id and also name
I want equivalent linq for below sql qwery
select app.employeeid, emp.employeename
from applicant app
join [EmployeeMaster] emp on app.employeeid = emp.EmployeeId
where app.employeeid like '%empid%' or emp.EmployeeName like '%empname%'
Can someone please help.
Welcome to the community Deepa,
You can use this query.
Please note that you cannot use like in the linq-to-sql, and you have to use Contains instead. Read this post for more information.
applicant
.Join(EmployeeMaster, app => app.employeeid, emp => emp.EmployeeId, (app, emp) => new { app, emp })
.Where(x => x.app.employeeid.Contains("1") || x.emp.Employeename.Contains("our"))
.Select(x => new
{
x.app.employeeid,
x.emp.Employeename,
});
By the way, if Applicant.employeeid is the same as EmployeeMaster.EmployeeId, then you don't need to join these two tables; unless your select or criteria clauses are different.
Try this:
var q = (from app in applicantList join emp in EmployeeMasterList on app.employeeid equals emp.EmployeeId where app.employeeid.Contains(empid) || emp.EmployeeName.Contains(empname) select new{ app.employeeid, emp.employeename }).ToList();

Multiple Join tables in classic report; Inserting only first row instead of checked row

I have question on classic report, which is based on multiple table joins. On which I have written process to loop and insert only checked box item. but it only select first item. However if do this on a single table it work properly. I would appreciate if someone can help me on inserted selected record when query is based on multiple joins.
My query is as below.
select apex_item.checkbox2(1, ord.rowid) sel,
apex_item.text(2,cust.name) Customer,
apex_item.text(3, it.item_id) Item,
apex_item.text(4,it.product_id) Product,
apex_item.text(5,price) price,
apex_item.text(6,quantity)||apex_item.hidden(7,ord.id) qty
from s_ord ord,
s_item it,
s_customer cust
where ord.id=it.ord_id
and cust.id=ord.customer_id
My process is as follow;
for i in 1..apex_application.g_f01.count loop
APEX_DEBUG_MESSAGE.LOG_MESSAGE(p_message => 'G_F01 : '||APEX_APPLICATION.G_F01(i), p_level => 1);
APEX_DEBUG_MESSAGE.LOG_MESSAGE(p_message => ' Q1 : '||APEX_APPLICATION.G_F02(i), p_level => 1);
APEX_DEBUG_MESSAGE.LOG_MESSAGE(p_message => ' P1 : '||APEX_APPLICATION.G_F03(i), p_level => 1);
end loop;
end;
As far as I can tell, you can't do that if a tabular form is created as a JOIN of two (or more) tables (didn't investigate why).
Here's what I do:
I base my tabular form on one table (the one I'm planning to work (insert, update) with
columns, that are normally fetched from other tables (using JOINs) are displayed using functions
That fixes the issue.
For example: you want to update employee's information, but also display department name they work in.
Don't:
select e.empno,
e.ename,
d.dname,
e.sal
from emp e join dept d on e.deptno = d.deptno;
Do:
create function f_dname (par_deptno in dept.deptno%type)
return dept.dname%type
is
retval dept.dname%type;
begin
select max(d.dname)
into retval
from dept d
where d.deptno = par_deptno;
return retval;
end;
/
select e.empno,
e.ename,
f_dname (e.deptno) dname, --> function instead of DEPT.DNAME
e.sal
from emp e; --> no join
I hope it'll help.

Oracle is having issues with hibernate generated query, generates query with _ in row num

I am using hibernate and using criteria query, database is Oracle. The below is the query that gets generated.
"
WITH query AS (
SELECT inner_query.*,
ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __hibernate_row_nr__
FROM (
select this_.MODIFIEDTIME as MODIFIED1_1_1_,
this_.FIELDNAME as FIELDNAM2_1_1_,
this_.EMPNBR as EMPNBR3_1_1_
from EMPLOYEEAUDIT this_
left outer join EMPLOYEE employee2_ on this_.EMPNBR=employee2_.EMPNBR
) inner_query
)
SELECT MODIFIED1_1_1_,FIELDNAM2_1_1_,EMPNBR3_1_1_
FROM query WHERE __hibernate_row_nr__ >= 1
AND __hibernate_row_nr__ < 10;"
It is throwing the below error:-
SQL Error: 911, SQLState: 22019
ORA-00911: invalid character
However, if i take the SQL query and repalce the hibernate_row_nr with hibernate_row_nr__ and run it in DbVisualizer it works. It seems Oracle is not able to recognize starting '_' as valid characters. How to fix this issue?
Below is my java code:-
public List<Employee> getEmployeeList(int start, int limit, AgSort sorter) throws UIFilterException {
DetachedCriteria detached = getEmployeeListCriteria(sorter, filters);
return (List<DealSetupAudit>) hibernateTemplate.findByCriteria(detached, start, limit);
}
private DetachedCriteria getEmployeeListCriteria(AgSort sorter) throws UIFilterException {
DetachedCriteria detached = getBaseCriteria(DealSetupAudit.class, sorter);
return detached;
}
protected <T> DetachedCriteria getBaseCriteria(Class<T> genericType, AgSort sorter) throws UIFilterException {
DetachedCriteria criteria = DetachedCriteria.forClass(genericType);
addSorter(criteria, sorter);
return criteria;
}
protected void addSorter(DetachedCriteria criteria, AgSort sort) {
if (sort != null) {
Order order = null;
if (sort.getDir().equalsIgnoreCase(Constants.DESC)) {
order = Order.desc(sort.getColumn());
} else {
order = Order.asc(sort.getColumn());
}
criteria.addOrder(order);
}
}
I am using Hibernate4, below is my application.properties :-
oracle.datasource.driver-class-name=oracle.jdbc.OracleDriver
oracle.datasource.url=******
oracle.datasource.username=*****
oracle.datasource.password=*****
oracle.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
oracle.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
Double quotes? Usually a really, really bad idea. I'd suggest you to avoid such things and use valid column names / aliases.
SQL> select dname _invalid_alias_
2 from dept
3 where deptno = 10;
select dname _invalid_alias_
*
ERROR at line 1:
ORA-00911: invalid character
SQL> select dname "_valid_alias_"
2 from dept
3 where deptno = 10;
_valid_alias_
--------------
ACCOUNTING
SQL>

hive sql join statment

I have a query
with ex as (
select z.num number, car.id as id, car.make as make, car.model, 'vehicles' as type from mytable mt LATERAL VIEW EXPLODE(mt.vehicles) vehiclestbl as honda
where car.working = true
union all
select z.num number, plane.id as id, plane.make as make, plane.model, 'flights' as type from mytable mt LATERAL VIEW EXPLODE(mt.flights) flightstbl as wings
where plane.active = true
union all
select z.num number, train.id as id, train.make as make, train.model, 'departures' as type from mytable mt LATERAL VIEW EXPLODE(mt.departures) departurestbl as wheels
where wheels.active = true
)
select ex0.*, 1499 as cost, model as location
from ex ex0
where mycolumn = 15
The end results looks something like this
number id make model type cost location
323 abc make1 model1 type1 1499 modelLoc1
329 xyz make2 model2 type2 1499 modelLoc2
984 lks make3 model3 type3 1499 modelLoc3
I am trying to join a column 'number' with another outside table. When ever i add a
INNER JOIN myothertable mot on mot.id = ex_id;
I get an 'cannot recognize input near' Error
In the CTE, the column is called number so I would expect the query to look like to look like:
select ex0.*, 1499 as cost, model as location
from ex ex0 inner join
myothertable mot
on mot.id = ex0.number;
where mycolumn = 15;

Fluent Nhibernate over legacy database in oracle

I am trying to connect to the existing db in oracle with fluentmapping .
I got
Mapping over CUstomer
public CustomerMapping()
{
Not.LazyLoad();
Id(x => x.Cst_Recid).GeneratedBy.Increment() ;
}
and i am trying to create session
public static ISessionFactory CreateSessionFactory()
{
return Fluently
.Configure()
.Database(OracleClientConfiguration.Oracle10.ConnectionString
("...."))
.Mappings(m =>
{
m.FluentMappings.AddFromAssemblyOf<CustomerMapping>();
})
.BuildConfiguration()
.BuildSessionFactory();
}
i have some trial class to try and create the sessionFactory
public class MyDataProvider
{
public static Customer GetCustomerById(long customerId)
{
ISessionFactory sessionFactory = SessionFactory.CreateSessionFactory();
ISession session = sessionFactory.OpenSession();
return session.Linq<Customer>().Where(x => x.Cst_Recid.Equals(temp)).FirstOrDefault();
}
}
i am not being able to get the Customer by Id even though I am getting to open session and activating ...
the test is very simple - only to check the select activity
[Test]
public void CanGetCustomerById()
{
MyDataProvider provider = new MyDataProvider();
Assert.AreEqual(33941, MyDataProvider.GetCustomerById(33941).Cst_Recid);
}
there is a mistake -
TestCase '...DataLayer.Tests.CustomerMappingTests.CanGetCustomerById'
failed: NHibernate.ADOException : could not execute query
[ select * from ( SELECT this_.Cst_Recid as Cst1_0_0_, this_.Cst_Customerid as Cst2_0_0_, this_.Cst_First_Name as Cst3_0_0_, this_.Cst_Group_Recid as Cst4_0_0_, this_.Cst_Insdbdt as Cst5_0_0_, this_.Cst_Insdbuser as Cst6_0_0_, this_.Cst_Joingroup_Dt as Cst7_0_0_, this_.Cst_Last_Name as Cst8_0_0_, this_.Cst_Lastupddt as Cst9_0_0_, this_.Cst_Lastupduser as Cst10_0_0_, this_.Cst_Tat_Lakoach_Meshalem as Cst11_0_0_, this_.Cst_Typeid as Cst12_0_0_, this_.Cst_Tziyun_Meshalem_Rashi_Only as Cst13_0_0_, this_.Cst_Tziyun_Mizdamen as Cst14_0_0_ FROM "Customer" this_ WHERE this_.Cst_Recid = :p0 ) where rownum <=:p1 ]
Positional parameters: #0>33941
[SQL: select * from ( SELECT this_.Cst_Recid as Cst1_0_0_, this_.Cst_Customerid as Cst2_0_0_, this_.Cst_First_Name as Cst3_0_0_, this_.Cst_Group_Recid as Cst4_0_0_, this_.Cst_Insdbdt as Cst5_0_0_, this_.Cst_Insdbuser as Cst6_0_0_, this_.Cst_Joingroup_Dt as Cst7_0_0_, this_.Cst_Last_Name as Cst8_0_0_, this_.Cst_Lastupddt as Cst9_0_0_, this_.Cst_Lastupduser as Cst10_0_0_, this_.Cst_Tat_Lakoach_Meshalem as Cst11_0_0_, this_.Cst_Typeid as Cst12_0_0_, this_.Cst_Tziyun_Meshalem_Rashi_Only as Cst13_0_0_, this_.Cst_Tziyun_Mizdamen as Cst14_0_0_ FROM "Customer" this_ WHERE this_.Cst_Recid = :p0 ) where rownum <=:p1]
----> System.Data.OracleClient.OracleException : ORA-00942: table or view does not exist
the query that he is trying to run is build automaticly by FluentNHibernate . If i remove the quoates the query executes right , it gets the result .. the trouble is that i can not change the query as i want .. maybe the problem is that we are using Oracle 11 g and FluentNhibernate adjusted only to Oracle 9 or 10 ?
will appreceate any help.
My previous answer was incorrect. Allow me to try again!
When you quote an object name in Oracle, it becomes case-sensative. Your CUSTOMER table is being quoted as "Customer" which is not the same as being quoted "CUSTOMER":
SQL> select * from "dual";
select * from "dual"
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select * from "Dual";
select * from "Dual"
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select * from "DUAL";
D
-
X
I still don't know anything about Fluid NHibernate, but is it possible to get it to look for a "CUSTOMER" table instead of a "Customers" table?
Alternatively, if nothing else is looking for a CUSTOMERS table, you could rename it to "Customers"... however, this will break references to a CUSTOMERS table:
SQL> create table CUSTOMERS (x int);
Table created.
SQL> insert into CUSTOMERS (x) values (1);
1 row created.
SQL> select * from CUSTOMERS;
X
----------
1
SQL> select * from "Customers";
select * from "Customers"
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select * from "CUSTOMERS";
X
----------
1
SQL> alter table CUSTOMERS rename to "Customers";
Table altered.
SQL> select * from CUSTOMERS;
select * from CUSTOMERS
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select * from "Customers";
X
----------
1
Good luck! I hope this helps...

Resources