从 C# 和 ODP.NET 调用包中的函数的代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18788509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Code for calling a function in a package from C# and ODP.NET
提问by user2776709
I've tried to write C# code with ODP.NET to call a function in a package. I'm getting the two errors below:
我试图用 ODP.NET 编写 C# 代码来调用包中的函数。我收到以下两个错误:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to INSERT_FUNC'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06550: line 1, column 7:
PLS-00221: 'INSERT_FUNC' is not a procedure or is undefined
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
My OracleCommand
is set up as:
我OracleCommand
的设置为:
cmd.CommandText = "PKG_NAME.INSERT_FUNC";
cmd.CommandType = CommandType.StoredProcedure;
- How should I pass parameters to the function below?
- Do I need to add a
ReturnValue
parameter? I've seen many forums discussing the need to add aReturnValue
parameter as the firstOracleParameter
on theOracleCommand
object.
- 我应该如何将参数传递给下面的函数?
- 我需要添加
ReturnValue
参数吗?我见过很多论坛讨论需要添加ReturnValue
参数作为第一个OracleParameter
在上OracleCommand
对象。
I would appreciate any suggestions.
我将不胜感激任何建议。
CREATE OR REPLACE
PACKAGE BODY pkg_name IS
FUNCTION insert_func (
i_description IN tableName.description%TYPE,
i_theme IN tableName.theme%TYPE,
o_id OUT tableName.id%TYPE,
o_error_msg OUT VARCHAR2 )
RETURN NUMBER
IS
l_program VARCHAR2(100) := 'PKG_NAME.INSERT_FUNC';
BEGIN
INSERT INTO tablea ( event_id, id, description, theme, lock_version )
VALUES ( rms12.tablea_seq.NEXTVAL, rms12.tablea_id_seq.NEXTVAL, i_description, i_theme, NULL );
INSERT INTO tableb ( id, description, theme )
VALUES ( rms12.id_seq.CURRVAL, i_description, i_theme );
SELECT rms12.id_seq.CURRVAL
INTO o_id
FROM dual;
RETURN 1;
EXCEPTION
WHEN OTHERS THEN
o_error_msg := sql_lib.create_msg(
'PACKAGE_ERROR', SQLERRM, l_program, TO_CHAR( SQLCODE ) );
RETURN 0;
END insert_func;
END pkg_name;
采纳答案by user2776709
This is my first question on this forum and I am happy to post to my own answer.
这是我在这个论坛上的第一个问题,我很高兴发布我自己的答案。
We can call an oracle package function using ODP.NET by setting CommandType.StoredProcedure
.
我们可以通过设置CommandType.StoredProcedure
.
ORA-06550: line 1, column 7:
PLS-00221: 'INSERT_FUNC' is not a procedure or is undefined
ORA-06550: line 1, column 7: PL/SQL: Statement ignored
If you get this error, just add this line as the first parameter on the command object:
如果出现此错误,只需将此行添加为命令对象的第一个参数:
cmd.Parameters.Add("Return_Value", OracleDbType.Int16,
ParameterDirection.ReturnValue);
Here is the working code:
这是工作代码:
using (var conn = new OracleConnection(oradb))
using (var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "PKG_NAME.INSERT_FUNC";
cmd.BindByName = true;
cmd.Parameters.Add("Return_Value", OracleDbType.Int16,
ParameterDirection.ReturnValue);
cmd.Parameters.Add("i_description", OracleDbType.Varchar2, 1000,
promotionEventSetupDetails.PromotionDescription,
ParameterDirection.Input);
cmd.Parameters.Add("i_theme", OracleDbType.Varchar2, 80,
promotionEventSetupDetails.PromotionTheme,
ParameterDirection.Input);
cmd.Parameters.Add("o_id", OracleDbType.Varchar2,
ParameterDirection.Output);
cmd.Parameters.Add("o_error_msg", OracleDbType.Varchar2,
ParameterDirection.Output);
conn.Open();
using (var dr = cmd.ExecuteReader())
{
// do some work here
}
}
回答by Ken
This must be new with a more recent version of Oracle. I was previously able to do this with the return value parameter listed after all of the input parameters in my C# code, but after running this on 12c I had this exact issue, which now works with this suggestion of putting the return val param first.
这必须是更新版本的 Oracle 的新功能。我以前能够使用在我的 C# 代码中的所有输入参数之后列出的返回值参数来执行此操作,但是在 12c 上运行此命令后,我遇到了这个确切的问题,现在可以使用将 return val 参数放在首位的建议。
回答by ppenchev
I have created a generic method that helps you get your function result
我创建了一个通用方法来帮助您获得函数结果
var result = await
dbManager.ExecuteFunctionResultAsync<Oracle.ManagedDataAccess.Types.OracleDecimal>(
functionName, parameters.List);
public async Task<T> ExecuteFunctionResultAsync<T>(string spName, IEnumerable<OracleParameter> paramaters)
{
using (OracleConnection connection = new OracleConnection(this.connectionString))
{
connection.Open();
using (OracleCommand comm = new OracleCommand(spName, connection))
{
comm.CommandType = CommandType.StoredProcedure;
comm.BindByName = true;
string returnParam = "return_value";
comm.Parameters.Add(new OracleParameter() {
ParameterName = returnParam,
Direction = ParameterDirection.ReturnValue,
OracleDbType = OracleDbType.Int16,
});
this.SetCommandParameters(comm, paramaters);
await comm.ExecuteNonQueryAsync();
var result = (T)comm.Parameters[returnParam].Value;
return result;
}
}
}
private void SetCommandParameters(OracleCommand command, IEnumerable<OracleParameter> paramaters)
{
if (paramaters != null)
{
foreach (OracleParameter p in paramaters)
{
command.Parameters.Add(p);
}
}
}