【问题标题】:C# - How to return a cursor from an Oracle procedure inside a packageC# - 如何从包内的 Oracle 过程返回游标
【发布时间】:2014-03-12 16:03:54
【问题描述】:

包装声明

这是包声明(Oracle 9i):

CREATE OR REPLACE
PACKAGE MyPackage AS

    PROCEDURE Results(start_date IN DATE, end_date IN DATE, brand IN NUMBER, summary OUT SYS_REFCURSOR);

END MyPackage;

包体

这是带有程序的包体:

CREATE OR REPLACE
PACKAGE BODY MyPackage AS

    PROCEDURE Results(start_date IN DATE, end_date IN DATE, brand IN NUMBER, summary OUT SYS_REFCURSOR) IS
        BEGIN
        OPEN summary FOR
            SELECT NVL(id, 0), type, order, SUM(alpha), SUM(beta), SUM(gamma), SUM(delta), SUM(epsilon), SUM(zeta), SUM(eta), SUM(theta), SUM(iota), SUM(kappa), SUM(lambda)
            FROM sample_owner.sample_table
            WHERE fecha BETWEEN start_date AND end_date AND id = brand
            GROUP BY id, type, order
            ORDER BY id, type, order;
        END Results;

END MyPackage;

代码

这是我尝试在 C# 中检索光标的方法(在 .NET 2.0 中使用 System.Data.OracleClient):

public static DataSet getResults(DateTime beginning, DateTime ending, int myBrand)
{

    string cs = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost)(PORT=myport))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=myservicename)));User ID=cat;Password=dog;Persist Security Info=True";
    OracleConnection conn = new OracleConnection(cs);
    OracleCommand cmd = conn.CreateCommand();

    cmd.CommandText = "MyPackage.Results";
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.Parameters.Add("start_date", OracleType.DateTime).Direction = System.Data.ParameterDirection.Input;
    cmd.Parameters["start_date"].Value = beginning;
    cmd.Parameters.Add("end_date", OracleType.DateTime).Direction = System.Data.ParameterDirection.Input;
    cmd.Parameters["end_date"].Value = ending;
    cmd.Parameters.Add("brand", OracleType.Int32).Direction = System.Data.ParameterDirection.Input;
    cmd.Parameters["brand"].Value = myBrand;
    cmd.Parameters.Add("summary", OracleType.Cursor).Direction = System.Data.ParameterDirection.Output;

    try
    {
        conn.Open();
        cmd.ExecuteNonQuery();
        DataSet ds = new DataSet("testDS");
        new OracleDataAdapter(cmd).Fill(ds);
        cmd.Parameters.Clear();
        conn.Close();
        return ds;
    }
    catch (Exception ex)
    {
        ex.ToString();
        return null;
    }

}

以下是我用来拨打电话的值:

int myBrand = 1;
DateTime beginning = new DateTime(2014, 1, 1);
DateTime ending = new DateTime(2014, 1, 31);
DataSet myDataSet = getResults(beginning, ending, myBrand);

数据集返回空,我没有收到任何错误消息。

我做错了什么?

【问题讨论】:

  • 乍一看,除了不使用 ODP.NET 之外,我没有看到任何不当行为。如果直接在 oracle 中单独执行,您的查询是否会返回值?
  • @T.S.查询在Oracle中直接执行时返回值(我使用的是Oracle SQL Developer)我过去使用过ODP.NET,但我不允许在这个项目中使用它

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


【解决方案1】:

看来我看到了您的问题。试试这个:

string cs = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost)(PORT=myport))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=myservicename)));User ID=cat;Password=dog;Persist Security Info=True";

using (OracleConnection conn = new OracleConnection(cs))
{
    using (OracleCommand cmd = conn.CreateCommand())
    {

        cmd.CommandText = "MyPackage.Results";
        cmd.CommandType = System.Data.CommandType.StoredProcedure;
        cmd.Parameters.Add("start_date", OracleType.DateTime).Direction = System.Data.ParameterDirection.Input;
        cmd.Parameters["start_date"].Value = beginning;
        cmd.Parameters.Add("end_date", OracleType.DateTime).Direction = System.Data.ParameterDirection.Input;
        cmd.Parameters["end_date"].Value = ending;
        cmd.Parameters.Add("brand", OracleType.Int32).Direction = System.Data.ParameterDirection.Input;
        cmd.Parameters["brand"].Value = myBrand;
        cmd.Parameters.Add("summary", OracleType.Cursor).Direction = System.Data.ParameterDirection.Output;

        try
        {
            conn.Open();
            DataTable dt = new DataTable("MyTable");
            OracleDataAdapter a = new OracleDataAdapter(cmd);
            DataSet ds = new DataSet("testDS");
            a.TableMappings.Add("MyTable", "sample_table"); // possible need for this
            a.Fill(ds);

            return ds;
        }
        catch 
        {
            return null;
        }
    }
 }

请注意,当您使用using (OracleConnection... 时,您不必担心关闭连接,因为当Dispose 调用 IDisposable 时它会关闭。

【讨论】:

  • 你从一开始就是对的;代码没有问题;我们刷新并重新启动了一切,终于能够在数据集可视化器中看到数据。感谢您的所有帮助
  • @AtanasMendes 很高兴它对你有用。你的代码应该执行,除了你不需要的额外内容:o)) 你试过我的代码了吗?
  • 我做到了,它也很有效,使用“使用”帮助我摆脱了一些混乱
猜你喜欢
  • 2011-01-24
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多