我有一个Oracle包与在出的参照光标具有一个过程。我的理解是,这是非常标准。
我不喜欢的是,我不得不写一吨的代码,只看到输出的事实。 So I asked this question它原来我可以通过创建一个包装程序的功能得到我想要的东西。
更新:看起来像我不需要的功能了,但它可能是值得知道,无论如何,那些好奇的看原来的问题和回答的更新。
这里的功能
FUNCTION GetQuestionsForPrint (user in varchar2)
RETURN MYPACKAGE.refcur_question
AS
OUTPUT MYPACKAGE.refcur_question;
BEGIN
MYPACKAGE.GETQUESTIONS(p_OUTPUT => OUTPUT,
p_USER=> USER ) ;
RETURN OUTPUT;
END;
这里就是我做SQL Developer来执行它
var r refcursor;
exec :r := mypackage.getquestionsForPrint('OMG Ponies');
print r;
所以从现在开始我可能会到ForPrint功能添加到我的所有过程。
这让我想,也许功能是我想要什么,我不需要的程序。
为了测试这个我试过从.NET执行功能,除了我不能这样做。这是真的事情是这样的。
using (OracleConnection cnn = new OracleConnection("Data Source=Test;User Id=Test;Password=Test;"))
{
cnn.Open();
OracleCommand cmd = new OracleCommand("mypackage.getquestionsForPrint");
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add ( "p_USER", "OMG Ponies");
cmd.Connection = cnn;
OracleDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(rdr.GetOracleValue(0));
}
Console.ReadLine();
}
所以我得到的错误。
getquestionsForPrint is not a procedure or is undefined
我试过的ExecuteScalar也具有相同的结果。
编辑以Slider345的意见,我也尝试设置命令类型为文本,使用下面的语句,我得到无效的SQL语句
mypackage.getquestionsForPrint('OMG Poinies');
和
var r refcursor; exec :r := mypackage.getquestionsForPrint('OMG Poinies');
使用ABHI的变化为命令文本
select mypackage.getquestionsForPrint('OMG Poinies') from dual
导致
在“0x61c4aca5”指令在“0x00000ce1”引用的内存。该内存不能为“read”。
我只是找错了树?
更新尝试添加的输出参数没有帮助。
cmd.Parameters.Add(null, OracleDbType.RefCursor, ParameterDirection.Output);
不知道名字应该是因为它的一个函数的返回值是什么(我试过空,空字符串,mypackage.getquestionsForPrint),但在所有的情况下,它只是导致
ORA-06550:第1行,第7列:PLS-00306:错误数量或类型的在调用 'getquestionsForPrint' 参数
最后编辑(希望)
显然Guddie问similar question我做了3个月后。他得到了这对答案
using (OracleConnection cnn = new OracleConnection("Data Source=Test;User Id=Test;Password=Test;"))
{
cnn.Open();
OracleCommand cmd = new OracleCommand("mypackage.getquestionsForPrint");
cmd.CommandType = CommandType.Text;
cmd.CommandText = "begin " +
" :refcursor1 := mypackage.getquestionsForPrint('OMG Ponies') ;" +
"end;";
cmd.Connection = cnn;
OracleDataAdapter da = new OracleDataAdapter(cmd);
cmd.ExecuteNonQuery();
Oracle.DataAccess.Types.OracleRefCursor t = (Oracle.DataAccess.Types.OracleRefCursor)cmd.Parameters[0].Value;
OracleDataReader rdr = t.GetDataReader();
while(rdr.Read())
Console.WriteLine(rdr.GetOracleValue(0));
Console.ReadLine();
}
我还没有与功能测试这一点,但我的存储过程。我指定REFCURSOR OUT参数。
command.Parameters.Add(new OracleParameter("refcur_questions", OracleDbType.RefCursor, ParameterDirection.Output));
如果你能得到与CommandType.Text工作的功能。我不知道你是否可以尝试添加上述除与方向参数:
ParameterDirection.ReturnValue
我使用Oracle.DataAccess版本2.111.6.0
我不得不去了,问题和答案之间上下找出完整的代码工作。所以我给的全部代码在这里,为我工作的人 -
var sql = @"BEGIN :refcursor1 := mypackage.myfunction(:param1) ; end;";
using(OracleConnection con = new OracleConnection("<connection string>"))
using(OracleCommand com = new OracleCommand())
{
com.Connection = con;
con.Open();
com.Parameters.Add(":refcursor1", OracleDbType.RefCursor, ParameterDirection.Output);
com.Parameters.Add(":param1", "param");
com.CommandText = sql;
com.CommandType = CommandType.Text;
com.ExecuteNonQuery();
OracleRefCursor curr = (OracleRefCursor)com.Parameters[0].Value;
using(OracleDataReader dr = curr.GetDataReader())
{
if(dr.Read())
{
var value1 = dr.GetString(0);
var value2 = dr.GetString(1);
}
}
}
希望能帮助到你。
我的猜测是,你不能调用一个函数类型的Command对象“的StoredProcedure”。你可以尝试类型的“文本”命令对象和命令文本中执行的是功能?
我知道这是一个很老的文章,但因为它花了这么久找出所有参与让.NET“战斗好”与甲骨文的细节,我想我应该把这个意见在那里为容纳任何人这个棘手的问题。
我经常打电话,在我们的环境中(.NET 3.5反对的Oracle 11g)返回REF_CURSOR Oracle存储过程。对于一个功能,你的确可以将参数命名为任何你想,但你需要设置其System.Data.ParameterDirection
= ParameterDirection.ReturnValue
然后ExecuteNonQuery
对OracleCommand
对象。在这一点上该参数的值将是甲骨文函数返回的ref_cursor。只投中值通过OracleDataReader
的OracleDataReader
和循环。
我会发布完整的代码,但我几年前写在VB.NET数据访问层,代码使用了该数据访问层(我们的企业内部网)的大部分是在C#。我想在一个单一的响应混合语言将是更大的失礼。