【问题标题】:Calling an Oracle Stored Procedure in C#在 C# 中调用 Oracle 存储过程
【发布时间】:2015-10-30 05:38:06
【问题描述】:

我正在尝试从 C# 程序调用 Oracle 存储过程。我正在使用SYS_REFCURSOR 存储过程的输出。当我到达该行时,我收到了无效的 SQL 错误

OracleDataReader reader = cmd.ExecuteReader() 

在我的 C# 程序中。我无法弄清楚为什么我会收到这个无效的 SQL 错误。

这是 C# 代码:

private void button1_Click(object sender, EventArgs e)
{
        string custname;
        int custnbr;

        List<Customer> customers = new List<Customer>();

        string oradb = "User Id=XXXXX;Password=XXXXX;Data Source=IP:PORT/xxxx;Pooling=false;";
        OracleConnection conn = new OracleConnection(oradb);

        try
        {
            conn.Open();
            OracleCommand cmd = new OracleCommand();
            cmd.Connection = conn;
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "PROCEDURE_TEST";

            OracleParameter oraP = new OracleParameter();
            oraP.ParameterName = "R_RECORDSET";
            oraP.OracleDbType = OracleDbType.RefCursor;
            oraP.Direction = System.Data.ParameterDirection.Output;

            cmd.Parameters.Add(oraP);
            cmd.CommandType = CommandType.Text;
            OracleDataReader reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                custnbr = reader.GetInt32(0);
                custname = reader.GetString(1);
                Customer custTemp = new Customer(custnbr, custname);
                customers.Add(custTemp);
            }

            foreach (var cust in customers)
            {
                textBox1.AppendText("Customer Number: " + cust.custnbr + "\t");
                textBox1.AppendText("Customer Name: " + cust.custname + "\r\n");
            }
        }

        catch(Exception ex)
        {
            textBox1.AppendText(ex.ToString());
            conn.Close();
        }
    }

这里是 Oracle 存储过程:

create or replace PROCEDURE PROCEDURE_TEST 
(   R_RECORDSET OUT SYS_REFCURSOR) AS 
BEGIN
OPEN R_RECORDSET FOR
SELECT POTCHARGECATEGORY, POTCHARGECODE, POTCHARGEDESCRIPTION,
       POTCHARGEBASEAMT, SUM(POTCHARGEQTY), SUM(POTCHARGEAMOUNT)

FROM riowner.ccum_customer customer

WHERE ic.collection_Datetime =
TO_DATE('30-SEP-2015 23:59:59','DD-MON-YYYY HH24:MI:SS')

GROUP BY POTCHARGECATEGORY, POTCHARGECODE, POTCHARGEDESCRIPTION,
         POTCHARGEBASEAMT;
END PROCEDURE_TEST;

【问题讨论】:

  • cmd.CommandType = CommandType.Text; 应该是cmd.CommandType = CommandType.StoredProcedure;
  • 您能否在 .NET 环境之外运行该过程(例如,使用 SQLPLUS、SQL Developer、Toad 或 Tora)?
  • 我认为这个显而易见的事情可以作为评论,但我会写下来作为答案@mason
  • 是的,存储过程在 Oracle SQL Developer 中工作。
  • @Shawn Command.Text &amp;&amp; Command.Type有区别

标签: c# oracle stored-procedures


【解决方案1】:
cmd.CommandType = CommandType.Text; 

应该是

cmd.CommandType = CommandType.StoredProcedure;

【讨论】:

  • 其实cmd.CommandType = CommandType.Text这行可以删掉,因为代码在打开连接后就已经将命令类型设置为存储过程了。
  • 这是真的.. 但是第二个分配覆盖了第一个分配,所以这也是一个很好的捕获@EdGibbs
【解决方案2】:

作为 MethodMan 答案的替代方案,您应该能够将命令类型保持为文本,但将您的 SQL 命令更改为:

cmd.CommandText = "BEGIN PROCEDURE_TEST END;";

MethodMan的方法如果你只需要调用一个过程就更好了,但是我上面做的方式可以让你做更多的过程,所以以后要注意了。

【讨论】:

  • 我也同意@Mason 有两种方法可以剥去这只猫的皮 +1
  • 您好,这是不正确的,您需要像这样添加分号 cmd.CommandText = "BEGIN PROCEDURE_TEST; END;";或“BEGIN PROCEDURE_TEST(1234); END;”;
  • @Rob 你确定吗?我不再有权访问 Oracle 来验证这一点。
  • @MethodMan 是的 - 在我们的 Oracle 版本 12 上测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
  • 2012-06-24
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多