8

我使用 odp.net 将 EntityFramework 与 Oracle 一起使用。参数化的 sql 查询不起作用。

var orderCode = "XYZ";
var set = ctx.Database.SqlQuery<Order>(
    "Select * from dwh.Orders where OrderCode = '{0}'"
    , orderCode
);

(或者)

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

但是,如果我对值进行硬编码,它就可以工作。

var set = ctx.Database.SqlQuery<Order>(
    "Select * from dwh.Orders where OrderCode = 'XYZ'",
    orderCode
);

有谁知道为什么?我在那个视图中有 150 列。那是问题吗?

更新: 使用 Oracle 参数的查询有效。问题是我在 :param 变量周围有单引号。

话虽如此,带有“{0}”的顶级查询不起作用。此外,以下 linq 查询不起作用。

var set = ctx.Orders.Where(a => a.OrderCode == orderCode); // Gets zero results.

当我对值进行硬编码时,它可以正常工作并正确获取结果。

var set = ctx.Orders.Where(a => a.OrderCode == "XYZ"); // Gets the results correctly.

更新 2: 查询与 Devart 的 dotconnect 驱动程序一起使用。看起来这是 odp.net 的问题。

有人有类似的问题吗?

4

2 回答 2

1

不确定您是否截断了示例,但如果您使用多个参数,则可能是问题所在:

Oracle麻烦中的参数化查询

尽管我看不出您的示例有什么问题,但我想知道您是否遇到了旧的 BindByName 问题。默认情况下,ODP.NET 按照将参数添加到集合中的顺序将参数绑定到查询,而不是根据您的需要基于它们的名称。尝试在您的 OracleCommand 对象上将 BindByName 设置为 true,看看是否能解决问题。

于 2013-06-14T01:05:47.713 回答
0

使用与 Oracle 相关的字符串时要小心,因为它具有填充定义为的字符串的怪癖CHAR(有关详细信息,请阅读CHAR 与 VARCHAR2 语义)。

假设您已经定义OrderCodeCHAR(4)XYZ然后 PL/SQL 将值空白填充到声明的长度,从而导致XYZ_(而_这里是填充字符)。

还假设非常量字符串orderCode被视为由于文档VARCHAR2中的此语句:

如果比较中的任一值具有数据类型 VARCHAR2,则使用非空白填充语义。也就是说,当比较长度不等的字符值时,PL/SQL 不做任何调整并使用准确的长度。

现在,如果您尝试执行 a a.OrderCode == orderCode,则左侧是CHAR,右侧是VARCHAR2,因此non-blank-padding使用了XYZ_=XYZ返回false

所以解决方案是使用类似的东西a.OrderCode.TrimEnd() == orderCode来使比较工作,因为.TrimEnd()它被翻译成RTRIM()返回VARCHAR2.

于 2018-02-12T10:34:48.247 回答