ODP.NET存储过程和可选参数

时间:2011-09-08 17:28:46

标签: c# .net oracle stored-procedures odp.net

我试过搜索,但没有找到我的问题的明确答案。我正在从SQL Server切换到Oracle,但仍然使用C#作为前端。我正在使用ODP.Net。我在Oracle中有一个存储过程,如下所示:

Create or Replace
Procedure GetFoo
   (cur_z OUT sys_refcursor,
    pub_date   IN   varchar2,
    fname      IN   varchar2 default null,
    lname      IN   varchar2 default null,
    phone      IN   varchar2 default null
   )
 IS
  BEGIN
    ---get some data
  END;

fname,lname和phone是可选参数。在我的C#代码中,我设置了OracleCommand.BindByName = true,我已经读过,应该允许我排除发送任何没有值要发送的参数。例如,我只需要发送光标,pub_date和电话搜索只匹配电话号码的记录。但是,当从C#调用它并且只添加游标,pub_date和phone的参数时,我不断收到错误:“调用'GetFoo'时错误的数字或类型的争论。然后,如果我发送游标,pub_date,和fname并保留其余的空我得到结果并且一切正常。看起来你不能跳过任何参数而不管BindByName设置。如果这是正确的行为然后我可以解决它但它似乎有点奇怪(嗯至少来自我的SQL Server经验)我想确保我没有错过任何东西。

感谢。

3 个答案:

答案 0 :(得分:2)

AFAIK BindByName旨在与按位置绑定形成对比......它与任何默认参数或类似物无关......

答案 1 :(得分:0)

根据我的经验,BindByName 对存储过程不起作用 - 仅用于查询。

但这对你来说真的不重要。您应该只在应用程序中使用单个方法调用此SP。在该方法的签名中使用默认参数,并始终将所有参数传递给ODP.Net。

object GetFoo(DateTime pubDate, string fName = null, string lName = null, string phone = null)
{

}

这样做,忘了它,把时间花在更重要的问题上。

答案 2 :(得分:0)

默认情况下,存储过程中对Oracle Parameters的绑定仅基于位置。

这意味着您必须按照在过程中声明的顺序添加参数,Oracle不会关心您将参数设置为的名称。

当您将绑定设置为BindByName时,您可以按任何顺序添加参数,只要它们具有相同的名称即可。在我看来,这比默认情况好很多。

但是,将BindByName设置为True或False不会影响参数是否需要参数。