从C#调用Oracle存储过程的问题

时间:2016-07-25 17:16:31

标签: c# oracle stored-procedures

这是我第一次使用C#调用Oracle存储过程,而且我不知道为什么我的代码无效。我想做的就是返回一个数据表。我的存储过程编译得很好 - 这里有一些描述它的伪代码:

CREATE OR REPLACE PROCEDURE SPROC_ONLINE
( Year IN NUMBER DEFAULT NULL
, Name IN VARCHAR2 DEFAULT NULL
, ID IN VARCHAR2 DEFAULT NULL
, refCursor OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN refCursor FOR
SELECT *
FROM TABLE
WHERE Field_Year = Year
  AND Field_Name = Name
  AND Field_ID = ID;  
END SPROC_ONLINE;

这是一些描述我的C#的伪代码:

public static DataTable search(int? Year, string Name, string ID)
    {            
        try
        {
            OracleConnection conn = getConnectionString();                
            OracleCommand cmd = new OracleCommand();
            cmd.Connection = conn;
            cmd.CommandText = "SPROC_ONLINE";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("Year", OracleDbType.Int32).Value = Year;
            cmd.Parameters.Add("Name", OracleDbType.Varchar2).Value = Name;
            cmd.Parameters.Add("ID", OracleDbType.Varchar2).Value = ID;                
            cmd.Parameters.Add("Output", OracleDbType.RefCursor).Direction = ParameterDirection.Output;

            DataTable dt = new DataTable();
            OracleDataAdapter da = new OracleDataAdapter(cmd);
            getConnectionString().Open();
            cmd.ExecuteNonQuery();
            da.Fill(dt);

            return dt;                
        }
        catch (Exception e) { throw new Exception("Error: " + e.Message); }
        finally { getConnectionString().Close(); }
    }

没有错误被抛出;只是当它不应该返回的数据表为空时(我正在测试的参数应该返回一些东西)。

我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

我认为您可能需要使用OracleDataReader

using(OracleCommand cmd = new OracleCommand("SPROC_ONLINE", TheConnection))
{
    using(OracleDataReader reader = new OracleDataReader())
    {
        while(reader.Read())
        {
            // Extract the values
            var a = reader["Year"];
            var b = reader["Name"];
            var c = reader["ID"];
            ... etc ...
        }
    }
}

答案 1 :(得分:0)

我的问题最终成了两倍;这是我最终得到的代码隐藏:

public static DataTable search(int? Year, string Name, string ID)
{
    try
    {
        using (var cmd = new OracleCommand("SPROC_ONLINE", getConnectionString()))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            var da = new OracleDataAdapter(cmd);
            cmd.Parameters.Add("Year", OracleDbType.Int32).Value = Year;
            cmd.Parameters.Add("Name", OracleDbType.Varchar2).Value = Name;
            cmd.Parameters.Add("ID", OracleDbType.Varchar2).Value = ID;
            cmd.Parameters.Add("Output", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
            DataTable dt = new DataTable();
            da.Fill(dt);
            return dt;
        }
    }
    catch (Exception e) {throw new Exception("Error: " + e); }
    finally {}
}

我的另一个问题是我没有意识到Oracle中的字符串比较是区分大小写的。显然,在SQL Developer中编译我的存储过程并尝试在Visual Studio中测试它之间,我并没有始终如一地输入" Name"参数;这解释了为什么会返回null数据表。我按如下方式调整了存储过程的WHERE子句:

WHERE Field_Year = Year
  AND UPPER(Field_Name) = UPPER(Name)
  AND Field_ID = ID;

现在一切正常。