【问题标题】:Using Oracle.ManagedDataAccess.Client to return a value from a function to c#使用 Oracle.ManagedDataAccess.Client 将值从函数返回到 c#
【发布时间】:2016-11-30 04:34:26
【问题描述】:

我在 Oracle 中有以下功能:

FUNCTION return_test (p_id varchar2) RETURN VARCHAR2
is
   p_return_val VARCHAR2 (500 CHAR) := 'test';
begin  
   return p_return_val;
end;

我正在尝试将值输入到我的 c# 代码中,如下所示:

var dbCommand = new OracleCommand();
string retVal;
string Function_query = "PKG_TEST.return_test";
dbConnection = new OracleConnection(ConnString);
dbConnection.Open();


OracleParameterCollection dbParams = dbCommand.Parameters;
dbParams.Add("p_return_val", OracleDbType.Varchar2, System.Data.ParameterDirection.ReturnValue);
dbParams.Add("p_id", OracleDbType.Varchar2, "123", System.Data.ParameterDirection.Input); 

OracleCommand cmd;
OracleParameter dbAddParam;
cmd = new OracleCommand(Function_query , dbConnection); 
cmd.CommandType = CommandType.StoredProcedure;
foreach (OracleParameter dbParam in dbParams)
{
    dbAddParam = (OracleParameter)dbParam.Clone(); // clones all settings
    cmd.Parameters.Add(dbAddParam);
}
retVal = cmd.ExecuteScalar().tostring();

调试时的错误是:

{"ORA-06502: PL/SQL: 数值或数值错误: 字符串缓冲区 太小\nORA-06512: 在第 1 行"}

【问题讨论】:

标签: c# oracle


【解决方案1】:

我从未与OracleParameterCollection 合作过。通常我会一一添加ParametersOracleCommand

不管怎样,试试这个:

OracleParameterCollection dbParams = dbCommand.Parameters;

dbParams.Add("p_return_val", OracleDbType.Varchar2, 500, null, ParameterDirection.ReturnValue);
dbParams.Parameters["p_return_val"].DbType = DbType.String; // Maybe this line is not required at Oracle.ManagedDataAccess. However, you must use it for Oracle.DataAccess

dbParams.Add("p_id", OracleDbType.Varchar2, "123", ParameterDirection.Input); 

string Function_query = "BEGIN :p_return_val := PKG_TEST.return_test(:p_id); END;";
cmd = new OracleCommand(Function_query , dbConnection);     
cmd.CommandType = CommandType.Text
cmd.Parameters.Add(dbParams);

cmd.ExecuteNonQuery();
retval = cmd.Parameters["p_return_val"].Value;

您不能在函数调用中使用方法ExecuteScalar(),它仅用于结果集,即SELECT ... 语句。见Data Provider for .NET Developer's Guide

【讨论】:

    【解决方案2】:

    感谢 Wernfried 的贡献。我现在就试试。与此同时,我们发现这可行:

    string query = "select PKG_TEST.return_test(:x) from dual";
    dbParams.Add("x", OracleDbType.Varchar2, QuoteID, System.Data.ParameterDirection.Input);
    var result = (string)dbManager.ExecuteScalar(query, dbParams, CommandType.Text);
    

    对我来说,它似乎是它的内联 SQL,我总是会尽量避免,但它确实有效。我有什么理由不使用它吗?

    【讨论】:

    • 尝试begin :p_return_val := PKG_TEST.return_test(:p_id); end;作为查询字符串。
    • Rory 如果您想评论答案,请使用评论。如果您提供更多详细信息,请使用您的问题。仅当您回答问题时才使用答案。
    • 最后我们被否决并被告知不要在c#代码中添加任何内联sql。我们不得不重新使用数据阅读器。 (我更新了我的显示名称)
    猜你喜欢
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    相关资源
    最近更新 更多