这是我第一次使用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(); }
}
没有错误被抛出;只是当它不应该返回的数据表为空时(我正在测试的参数应该返回一些东西)。
我在这里做错了什么?
答案 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;
现在一切正常。