Fluent Nhibernate over legacy database in oracle - 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...

Related

EF Core with GroupBy - column ambiguously defined

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.

How can i convert this raw query to eloquent scope?

SELECT *
FROM employment_informations t1
WHERE NOT EXISTS (
SELECT 1 FROM employment_informations t2
WHERE t1.employee_id = t2.employee_id
AND t1.field_name = t2.field_name
AND t2.created_at > t1.created_at
)
This is what I have so far.
$builder->whereNotExists(function ($builder) {
$builder->select(\DB::raw(1))
->from('employment_informations t2')
->whereRaw('employment_informations.employee_id = t2.employee_id
AND employment_informations.field_name = t2.field_name
AND t2.created_at > employment_informations.created_at
');
});
I don't know how to alias table in eloquent scope.
here's the error:
[09:15:38] LOG.error: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'hris.employment_informations t2' doesn't exist (SQL: select count(*) as aggregate from `employment_informations` where not exists (select 1 from `employment_informations t2` where employee_id = t2.employee_id
AND field_name = t2.field_name
AND t2.created_at > created_at)) {"userId":1,"exception":{"errorInfo":["42S02",1146,"Table 'hris.employment_informations t2' doesn't exist"]}}
doesn't work using as either:
->from('employment_informations as t2')
If possible I want to alias the table with t1 and the subquery table to t2, but I don't know how to do it.
Laravel supports aliases on tables and columns with AS. Try
$query = DB::table('tablename AS t')->select('t.id AS uid')->get();

ORA-00936: expression absente + ORA-02063: précédant line de LIENBD_S1 Oracle

Can you help me find the error here? I do not understand why it is not working..
CREATE TABLE Commande2 AS (SELECT * FROM Commande#lienBD_S1 WHERE numF NOT IN (SELECT numF FROM Fournisseur1#lienBD_S1));
When I execute the query without the CREATE TABLE like this
SELECT * FROM Commande#lienBD_S1 WHERE numF NOT IN (SELECT numF FROM Fournisseur1#lienBD_S1);
it works.
I found an other way to make it work !
I created a table Fournisseur2 That contain the the lines that are NOT IN Fournisseur1 and used it to create my table Commande2 like this :
CREATE TABLE Fournisseur2 AS (SELECT * FROM Fournisseur#lienBD_S1 WHERE ville <> 'Paris');
CREATE TABLE Commande2 AS (SELECT * FROM Commande#lienBD_S1 WHERE numF IN (SELECT numF FROM Fournisseur2));

Oracle Invalid Identifier (with Inner Join)

I'm having an "Invalid Identifier" in Oracle because of the "B.username" (username column does exist in USER table). When i remove this, it's working fine. How to resolve this issue? I came from a MySQL background.
SELECT * FROM (SELECT qNA.assignment, qNA.regDate, B.username, (
SELECT DISTINCT NVL(idx, 0)
FROM EK_USERGRADE
WHERE year = (SELECT DISTINCT userGradeNo FROM EK_USER WHERE ID = qNA.userIdx)
) AS userGradeIdx
FROM EK_NEWTESTAPPLICANT qNA
WHERE IDX = :idx ) A
INNER JOIN EK_USER B ON (A.userIdx = B.ID)
Let's try this with a simplified version of your query:
-- test tables
create table NEWTESTAPPLICANT as select 1 useridx from dual ;
create table B as select 1 id, 'name1' username from dual ;
-- query
select *
from (
select B.username
from NEWTESTAPPLICANT qNA
) A join B on A.useridx = B.id ;
-- ORA-00904: "B"."USERNAME": invalid identifier
There's no "username" column in the NEWTESTAPPLICANT table, which causes the error. A LATERAL inline view (examples see here) may do the trick ...
-- query
select
*
from B, lateral (
select B.username
from NEWTESTAPPLICANT qNA
) A ;
-- result
ID USERNAME USERNAME
1 name1 name1
This works with Oracle 12c.
The problem is, that both your virtual table A and users B have the same column name "username". Specify alias in the main select, like "Select A.* , B.* from(...".
Is it ORA-00903?
User is a reserved word are you sure you created this table? Table name cannot be a reserved word.

Oracle select schema depending on select-statement

I have have two schemas with the same table. e.g schema1.adress and schema2.adress.
Both tables are identical.
Layout of table customer:
customerno: integer
name: varchar2(50)
Now I want to get the customers of schema 1 using something like
"select * from customer where schemaname = 1" or
"select * from customer where schemaname = 2"
Is there a mechanism in Oracle that can switch the schema depending on a criteria in a select-statement?
Before you ask: for a new project I have to query legacy schemas. I cannot change the schema, but I can set any permission on the schema / user.
Any ideas?
Thanks for any response,
Sven
You could create a private synonym for the user for the schema.table you want them to access,
create synonym user1.customer for schemaname1.customer;
create synonym user2.customer for schemaname2.customer;
Then your queries would always just be select * from customer;
So you are logged in as the same user both when you want to select from schema1.customer and select from schema2.customer?
A possible way can be something like:
select *
from (
select 'schema1' schema$name, c.* from schema1.customer c
union all
select 'schema2' schema$name, c.* from schema2.customer c
)
where schema$name = 'schema1'
If you can create views, it can be an idea to create a view like:
create or replace view customer_view as
select 'schema1' schema$name, c.* from schema1.customer c
union all
select 'schema2' schema$name, c.* from schema2.customer c
That makes it possible to do:
select *
from customer_view
where schema$name = 'schema1'
Whether you use view or not, Oracle optimizer can in most cases like this push the predicate "where schema$name = 'schema1'" into the UNION ALL and then it recognizes that it does not need to access schema2.customer at all.

Resources