Reputation: 1645
I am using EntityFramework with Oracle using odp.net. The parameterized sql query does not work.
var orderCode = "XYZ";
var set = ctx.Database.SqlQuery<Order>(
"Select * from dwh.Orders where OrderCode = '{0}'"
, orderCode
);
(or)
var set1 = ctx.Database.SqlQuery<Order>(
"Select * from dwh.Orders where OrderCode = ':param'",
new OracleParameter("param", orderCode)
);
Console.WriteLine(set.Count() + ", " + set1.Count()); //Gives 0, 0
However, if I have hard code the value, it works.
var set = ctx.Database.SqlQuery<Order>(
"Select * from dwh.Orders where OrderCode = 'XYZ'",
orderCode
);
Does any one know why? I have 150 columns in that view. Is that a problem?
UPDATE: The query with the Oracle parameter works. The problem is that I had single quotes around the :param variable.
That being said, top query with '{0}' does not work. Also, the following linq query does not work.
var set = ctx.Orders.Where(a => a.OrderCode == orderCode); // Gets zero results.
When I hardcode the value, it works and fetches the results correctly.
var set = ctx.Orders.Where(a => a.OrderCode == "XYZ"); // Gets the results correctly.
UPDATE 2: The queries work with dotconnect driver from Devart. Looks like this is an issue with odp.net.
Anyone has similar problems?
Upvotes: 9
Views: 3127
Reputation: 5155
Be careful when using strings in connection with Oracle as it has the quirk to pad strings that are defined as CHAR
(read CHAR versus VARCHAR2 Semantics for details).
Lets assume you have defined OrderCode
as CHAR(4)
with a value of XYZ
then PL/SQL blank-pads the value to the declared length which results in XYZ_
(whereas _
is the padding character here).
Also assume that the non-constant string orderCode
is treated as VARCHAR2
due to this statement in the docs:
If either value in a comparison has datatype VARCHAR2, non-blank-padding semantics are used. That is, when comparing character values of unequal length, PL/SQL makes no adjustments and uses the exact lengths.
Now if you try to do a a.OrderCode == orderCode
then the left side is CHAR
and the right side is VARCHAR2
and therefore non-blank-padding
is used which results in XYZ_
= XYZ
returning false
.
So the solution is to use something like a.OrderCode.TrimEnd() == orderCode
to make the comparison work as .TrimEnd()
is translated into the PL/SQL RTRIM()
function which returns a VARCHAR2
.
Upvotes: 0
Reputation: 5761
Not sure if you truncated your example, but if you are using multiple parameters, this might be the problem:
Parameterized query in Oracle trouble
Although I can't see anything wrong with your example, I wonder if you're being hit by the old BindByName problem. By default, ODP.NET binds parameters to the query in the order in which they are added to the collection, rather than based on their name as you'd like. Try setting BindByName to true on your OracleCommand object and see if that fixes the problem.
Upvotes: 1