【问题标题】:Return of Oracle Stored Procedure using OracleDataReader (ODAC)使用 OracleDataReader (ODAC) 返回 Oracle 存储过程
【发布时间】:2013-06-28 06:00:31
【问题描述】:

我在使用 OracleDataReader(Oracle.DataAccess.Client) 从 Oracle 存储过程输出数据时遇到问题。

程序:

    procedure LOAD_BL_REQ_2(P_XML CLOB, P_XML_OUT out CLOB) is
    BEGIN

     P_XML_OUT    := 'TEST1111';

     exception
     when others then
        P_XML_OUT   := 'LOAD_BL_REQ: Error'|| SQLERRM;
    END;

C#代码:

    OracleCommand cmd = new OracleCommand();
    cmd.Connection = OraConnection;
    cmd.CommandText = "IBS.BNT_EQ.LOAD_BL_REQ_2";
    cmd.CommandType = System.Data.CommandType.StoredProcedure;

    OracleParameter result = new OracleParameter();
    result.ParameterName = "P_XML_OUT";
    result.OracleDbType = OracleDbType.Clob;
    result.Direction = System.Data.ParameterDirection.Output;
    cmd.Parameters.Add(result);

    OracleParameter XMLString = new OracleParameter();
    XMLString.ParameterName = "P_XML";
    XMLString.OracleDbType = OracleDbType.Varchar2;
    XMLString.Direction = System.Data.ParameterDirection.Input;

    OracleDataReader dr;

    cmd.Transaction = OraConnection.BeginTransaction();
    try
    {
        XMLString.Value = XML;
        cmd.Parameters.Add(XMLString);
        dr = cmd.ExecuteReader();
        cmd.Transaction.Commit();
    }
    catch (OracleException ex)
    {
        cmd.Transaction.Rollback();
        Log(2, "Transaction fail, exception: " + ex.ToString());
        ORADisconnect();
        return "";
    }

在调试过程中我看到了博士:

    Depth: 0
    FetchSize: 131072
    FieldCount: 0
    HasRows: false

为了测试,我添加计数代码:

    while (dr.Read())
    {
        count++;
    }

计数在任何时候都是 0。

这段代码(例如):

  if(dr.IsDBNull(0))
  {
   //etc...
  }

  OracleClob oclob;
  oclob = dr.GetOracleClob(0);

返回异常:

  dr.isdbnull exception: System.InvalidOperationException: Operation is not valid due to the current state of the object.
  at Oracle.DataAccess.Client.OracleDataReader.IsDBNull(Int32 i)
  at GlobalFunc.ORA_BlackList_Test(String XML) in c:\inetpub\project\App_Code\GlobalFunc.cs:line 474

最后我需要从 Oracle SP 检索 CLOB 数据,但现在在这一步停止。 使用:Visual Studio 2012、ASP.Net(网络项目,但我将此代码写入 WinForms 应用程序并遇到同样的问题)、oracle.dataaccess.dll 4.112.3.0

【问题讨论】:

    标签: c# odp.net odac


    【解决方案1】:

    我找到了解决方案!然而,一切都很简单:

            string XML = "XML Data";
            OracleCommand cmd = OraConnection.CreateCommand();
    
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "IBS.BNT_EQ.LOAD_BL_REQ_2";
    
            OracleParameter result = new OracleParameter();
            result.ParameterName = "P_XML";
            result.OracleDbType = OracleDbType.Clob;
            result.Value = XML;
            result.Direction = System.Data.ParameterDirection.InputOutput;
            cmd.Parameters.Add(result);
    
            try
            {
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.ToString());
            }
    
            string str = (result.Value as OracleClob).Value;
            MessageBox.Show("Val: " + str);
    
            OraConnection.Close();
    

    可能对某人有用。

    【讨论】:

    • 谢谢,这正是我需要的:string str = (result.Value as OracleClob).Value;
    【解决方案2】:

    您必须调用dataReader.Read() 才能真正从DataReader 获取一些数据。

    另请注意,ODP.NET 默认忽略参数名称并按位置绑定。这意味着在您的示例中,参数是错误的。创建命令后调用cmd.BindByName = true 或按正确顺序将它们添加到命令的Parameters 集合中。

    【讨论】:

    • 添加cmd.BindByName = true,但没有任何改变。我试试这个代码: while (dr.Read()) { count++; } 计数为 0...
    • @PavelShaposhnikov 然后当然dr.IsDBNull 会抛出一个InvalidOperationException,因为您阅读了整个结果集。对dr.Read() 的最后一次调用没有返回任何数据,因此dr.IsDBNull 没有什么可做的。在该循环内调用 dr.IsDBNull(或者更好地将循环更改为单个 dr.Read 调用,因为该过程永远不会有超过一个结果行)。
    • cremor,不是关于dr.IsDBNull 的问题,而是关于 SP 空返回的问题。我添加了最后一个代码来演示没有返回数据。结果,dr.IsDBNull 随时给出异常,是否调用我是dr.Read()...如果我添加dr.GetOracleClob(0)(这是我的最终目标)而不是dr.IsDBNull,我也会捕获异常。我正在编辑主要帖子以便更好地查看此内容。
    【解决方案3】:

    Procedure view,, 谢谢,快跑!

     protected void Save(object sender, EventArgs e)
        {
            OracleConnection conn = new OracleConnection("Data Source=XE;Persist Security Info=True;Password=*****;User ID=WINCELL");
            string procedure = "WINCELL_API.ADD_CAMPAIGN";
            OracleCommand cmd = new OracleCommand(procedure, conn);
           // DataTable dt = new DataTable();
           // OracleDataAdapter da = new OracleDataAdapter();
    
            string xml = "<campaign>";
            xml += "\n";
            xml += "<campaignInfo>";
            xml += "\n";
            xml += "<name>" + TextBox1.Text + "</name>";
            xml += "\n";
            xml += "<startDate>" + TextBox2.Text + "</startDate>";
            xml += "\n";
            xml += "<period>" + TextBox3.Text + "</period>";
            xml += "\n";
            xml += "<handsetStatu>" + TextBox4.Text + "</handsetStatu>";
            xml += "\n";
            xml += "<ServiceID>" + TextBox5.Text + "</ServiceID>";
            xml += "\n";
            xml += "</campaignInfo>";
            xml += "\n";
            xml += "</campaign>";
    
    
            TextBox6.Text = xml;
    
                conn.Open();
                cmd.CommandType = CommandType.StoredProcedure;
                OracleParameter param = new OracleParameter();
                param.ParameterName = "";
                param.OracleDbType = OracleDbType.Clob;
                param.Value = xml;
                param.Direction = System.Data.ParameterDirection.InputOutput;
                cmd.Parameters.Add(param);
                try
                {
                cmd.ExecuteNonQuery(); 
                }
                catch (Exception ex)
                {
                Label1.Text = error" + ex.ToString();
    
                }
            //string str = (param.Value as OracleClob).Value;
            //Label1.Text = "val: " + str;
        }
    

    【讨论】:

      猜你喜欢
      • 2011-01-31
      • 2019-06-03
      • 2014-08-31
      • 1970-01-01
      • 2023-04-06
      • 2011-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多