【问题标题】:What is the right way to call an Oracle stored function from ado.net and get the result?从 ado.net 调用 Oracle 存储函数并获得结果的正确方法是什么?
【发布时间】:2010-12-18 21:57:11
【问题描述】:

我有一个使用 ado 连接到 Oracle 数据库的 vb.net 代码库。我们有很多我们调用的存储过程,其中一些带有多个输出参数。但是,我现在需要调用一个存储的函数,我不清楚如何将函数的结果返回到我的 VB 代码中。

编辑:我返回一个整数。

如何从 ado.net 正确调用 oracle 存储函数?

【问题讨论】:

  • 函数返回什么?

标签: oracle stored-procedures ado.net function stored-functions


【解决方案1】:

我假设您使用的是 ODP.net(.net 的本机 Oracle 客户端)。

假设您有 2 个这样的 Oracle 存储函数:

   FUNCTION my_func
   (
      p_parm1 VARCHAR2
    , p_parm2 NUMBER
   ) RETURN VARCHAR2
   AS
   BEGIN
      RETURN p_parm1 || to_char(p_parm2);
   END;

   FUNCTION my_func2 RETURN SYS_REFCURSOR
   AS
      v_cursor SYS_REFCURSOR;
   BEGIN
      OPEN v_cursor FOR
         SELECT 'hello there Sean' col1
           FROM dual
          UNION ALL
         SELECT 'here is your answer' col1
           FROM dual;      
      RETURN v_cursor;          
   END;

其中一个函数返回 VARCHAR2,另一个返回 ref 游标。在 VB 方面,您可以这样做:

Dim con As New OracleConnection("Data Source=xe;User Id=sandbox;Password=sandbox; Promotable Transaction=local")

Try
    con.Open()
    Dim cmd As OracleCommand = con.CreateCommand()
    cmd.CommandText = "test_pkg.my_func"
    cmd.CommandType = CommandType.StoredProcedure

    Dim parm As OracleParameter

    parm = New OracleParameter()
    parm.Direction = ParameterDirection.ReturnValue
    parm.OracleDbType = OracleDbType.Varchar2
    parm.Size = 5000
    cmd.Parameters.Add(parm)

    parm = New OracleParameter()
    parm.Direction = ParameterDirection.Input
    parm.Value = "abc"
    parm.OracleDbType = OracleDbType.Varchar2
    cmd.Parameters.Add(parm)

    parm = New OracleParameter()
    parm.Direction = ParameterDirection.Input
    parm.Value = 42
    parm.OracleDbType = OracleDbType.Int32
    cmd.Parameters.Add(parm)

    cmd.ExecuteNonQuery()
    Console.WriteLine("result of first function is " + cmd.Parameters(0).Value)

    '''''''''''''''''''''''''''''''''''''''''''''
    ' now for the second query
    '''''''''''''''''''''''''''''''''''''''''''''
    cmd = con.CreateCommand()
    cmd.CommandText = "test_pkg.my_func2"
    cmd.CommandType = CommandType.StoredProcedure

    parm = New OracleParameter()
    parm.Direction = ParameterDirection.ReturnValue
    parm.OracleDbType = OracleDbType.RefCursor
    cmd.Parameters.Add(parm)

    Dim dr As OracleDataReader = cmd.ExecuteReader()
    While (dr.Read())
        Console.WriteLine(dr(0))
    End While

Finally
    If (Not (con Is Nothing)) Then
        con.Close()
    End If
End Try

【讨论】:

    【解决方案2】:
    ' Create ODP database connection 
    Dim constr As String = (("User Id=" & Properties.Settings.[Default].DbUid & "; Password=") + Properties.Settings.[Default].DbPwd & "; Data Source=") + Properties.Settings.[Default].DbTnsName & "; Pooling=false"
    Dim con As New OracleConnection(constr)
    Dim cmd As New OracleCommand()
    cmd.Connection = con
    
    Try
        cmd.CommandText = "test_pkg.test_function"
        cmd.CommandType = CommandType.StoredProcedure
    
        'Always add return parameter before other parameters when calling database functions in .net!!
        cmd.Parameters.Add("result", OracleDbType.Int32).Direction = ParameterDirection.ReturnValue
        cmd.Parameters.Add("param1", OracleDbType.Varchar2).Value = "something"
        cmd.Parameters.Add("param2", OracleDbType.Varchar2).Value = "something else"
        con.Open()
        cmd.ExecuteNonQuery()
    
        Console.WriteLine(CInt(cmd.Parameters("result").Value))
    Finally
        ' Cleanup
        con.Close()
        cmd.Dispose()
        con.Dispose()
    End Try
    

    【讨论】:

    • 我还没有尝试过,但是指定结果应该是第一个参数绝对看起来像一个可以产生最大差异的精细细节:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    • 2015-06-24
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    相关资源
    最近更新 更多