ODP.NET OracleCommand可选参数永远不会获得默认值

时间:2016-03-22 14:30:02

标签: vb.net oracle odp.net

当我从PL / SQL包调用函数时,有一个IN可选参数(Date),默认值为SYSDATE。

当我执行我的命令时,我没有选择,只能添加参数。即使没有设置值,该函数也始终接收null作为输入值,因此它永远不会影响默认值。

            Dim cmd As New OracleCommand(con)
            cmd.CommandType = CommandType.StoredProcedure
            cmd.CommandText = "PACK.RefreshData"

            Dim param1 As New OracleParameter()
            param1.Direction = ParameterDirection.Input
            param1.ParameterName = "p_date"
            param1.DbType = DbType.Date
            cmd.Parameters.Add(param1)

            param1 = New OracleParameter()
            param1.Direction = ParameterDirection.Output
            param1.ParameterName = "po_errorCode"
            param1.DbType = DbType.String
            cmd.Parameters.Add(param1)

            param1 = New OracleParameter()
            param1.Direction = ParameterDirection.Output
            param1.ParameterName = "po_errorDescription"
            param1.DbType = DbType.String
            cmd.Parameters.Add(param1)

            con.Open()
            cmd.ExecuteNonQuery()

在另一个问题中,有人说设置为true的命令属性BindByName仅适用于常规查询,而不适用于storedProcs。那么,如果不使用IN参数传递值,我该怎么做才能调用函数?

这是Stored Proc标题

Procedure RefreshData
(
  p_date IN DATE := SYSDATE, 
  po_errorCode OUT  varchar2, 
  po_errorDescription OUT   varchar2
);

N.B。 :我正在使用Oracle.DataAccess.dll版本4.112.4.0

更新:以下是来自oracle主题的解释,来自我的回答:

我认为它归结为DervieParameters正在为所有proc参数派生参数,即使它们具有默认值,并且在我看来这是正确的行为。一旦在集合中有参数,如果没有为它们赋值,则将传递null。

您可能需要做的是

1)最好的选择,不是首先使用deriveparameters,而是手动构建参数集合,只为你不想拥有默认值的东西添加参数:

DeriveParameters会导致数据库往返,并且只能在设计时使用。为了避免在生产环境中进行不必要的数据库往返,DeriveParameters方法本身应该替换为DeriveParameters方法在设计时返回的显式参数设置。

2)如果您想继续使用DeriveParameters,请从OracleParameters集合中删除不需要的参数。

2 个答案:

答案 0 :(得分:0)

如果默认值参数不在参数链的尾部,则应执行命名参数调用以避免传递此default-value参数。我认为您的数据提供程序不支持此调用类型,因此您应该将此调用包装在匿名pl \ sql块中,如下所示:

CommandType

然后执行以前在VB代码中执行的操作(当然,您Text将为Procedure RefreshData ( po_errorCode OUT varchar2, po_errorDescription OUT varchar2, p_date IN DATE := SYSDATE ); )。

另一个解决方案是将default-value参数移动到参数链的末尾,如下所示:

declare @userId table (uid int)
declare @feedId table (id int)

insert into @userid(uid)
select id 
from Users 
where name = @userName

insert into @feedid(id)
select feedid 
from userstofeed 
where userid in (select uid from @userId)

select * from feed where id in (select id from @feedId)

答案 1 :(得分:0)

最后,我已经能够找到一种方法来使用这个线程调用该过程:

https://community.oracle.com/thread/2248928?tstart=0

这是我更正后的代码:

            con.Open()
            cmd = con.CreateCommand()
            cmd.CommandType = CommandType.StoredProcedure
            cmd.CommandText = "Pack.RefreshData"
            cmd.BindByName = True

            OracleCommandBuilder.DeriveParameters(cmd)
            cmd.Parameters.RemoveAt(0) 'I remove the optional parameter 

            cmd.ExecuteNonQuery()

然后我检索了我的OUT参数

            Dim outPrm1 as String = ""
            If cmd.Parameters("po_errorDescription").Value IsNot Nothing Then
                outPrm1 = cmd.Parameters("po_errorDescription").Value
            End If