简体   繁体   English

C#-如何从包内的Oracle过程返回游标

[英]C# - How to return a cursor from an Oracle procedure inside a package

Package

Package Declaration 包装声明

This is the package declaration ( Oracle 9i ): 这是软件包声明( 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;

Package Body 包装体

This is the package body with the procedure: 这是带有以下步骤的程序包主体:

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;

Code

Here is how I try to retrieve the cursor in C# (using System.Data.OracleClient in .NET 2.0 ): 这是我尝试在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;
    }

}

And here are the values that I'm using to make the call: 这是我用来进行呼叫的值:

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

The dataset returns empty, and I'm not receiving any error messages. 数据集返回空,并且我没有收到任何错误消息。

What am I doing wrong? 我究竟做错了什么?

Looks like I see your issue. 看来我看到了您的问题。 Try this: 尝试这个:

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;
        }
    }
 }

Note that when you use using (OracleConnection... you need not to worry about closing connection because it is closed when Dispose called on IDisposable. 请注意,当使用using (OracleConnection...您不必担心关闭连接,因为在IDisposable上调用Dispose时该连接已关闭。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM