我正在尝试在.net 4.5
中执行以下存储过程 PROCEDURE my_procedure (
a_cursor OUT t_cursor,
return_value OUT VARCHAR2,
a_type VARCHAR2,
a_time DATE,
a_id VARCHAR2,
a_arg1 VARCHAR2,
a_from VARCHAR2,
a_gl2 VARCHAR2,
a_arg2 DATE DEFAULT NULL,
a_templ VARCHAR2 DEFAULT NULL
)
这些参数中的大多数都可以为null。在toad我可以用:
执行它BEGIN package.my_procedure( :c, :out, 'arg', '', '123' , '', '', '', '', ''); END;
在C#中,我正在尝试以下方法:
object[] parameters = {
new OracleParameter("arg1", arg1),
new OracleParameter("arg", "arg"),
new OracleParameter("empti", ""),
new OracleParameter("out", OracleDbType.Varchar2, ParameterDirection.Output),
new OracleParameter("c", OracleDbType.RefCursor, ParameterDirection.Output)
};
const string sql = "BEGIN package.my_procedure
(:c, :out, :arg, :empti, :arg1 , :empti, :empti, :empti, :empti, :empti); END;";
res = _projectRepository.ExecuteStoredProcedure(sql, parameters);
我收到以下错误
Test method Tests.repository.RepositoryTests.TestMethod1 threw exception:
Oracle.DataAccess.Client.OracleException: ORA-06550:
line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'my_procedure'ORA-06550:
line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'my_procedure'ORA-06550:
line 1, column 7:
PL/SQL: Statement ignored
我尝试使用和不使用可选参数以及使用/不使用return_value /:out参数。
我正在使用Oracle.DataAccess提供程序v.4.1212.3.0。它适用于没有那么多参数/只有一个out参数(光标)的其他存储过程。
编辑:我发现一个错误,我需要先在参数数组中输出参数;
new OracleParameter("c", OracleDbType.RefCursor, ParameterDirection.Output),
new OracleParameter("out", OracleDbType.Varchar2, ParameterDirection.Output),
new OracleParameter("arg1", "arg1"),
new OracleParameter("empti", ""),
new OracleParameter("arg", arg),
};
现在我收到了错误:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
似乎是一个数据库错误,但看起来很奇怪,因为我可以从toad执行相同的命令而不会收到错误。
答案 0 :(得分:3)
使用VARCHAR2
作为OUPUT
时,需要提供字符缓冲区的大小。但是构造函数重载在这里没有用,你需要手动创建变量来设置所需的属性。
// Specify a size adequate for the full return value.
OracleParameter returnValue =
new OracleParameter("return_value", OracleDbType.Varchar2, 100);
returnValue.ParameterDirection = ParameterDirection.Output;
object[] parameters = {
returnValue,
// other parameters here
};
我会留下原来的答案,因为它会处理问题的第一个版本。
提供的错误是正确的,您没有在通话中提供正确数量的参数。让我们看看Toad for Oracle可以使用的原始工作代码,并将它们映射到参数名称:
BEGIN
package.my_procedure(a_cursor => :c,
return_value => :out,
a_type => 'arg',
a_time => '',
a_id => '123',
a_arg1 => '',
a_from => '',
a_gl2 => '',
a_arg2 => '', -- DEFAULT NULL
a_temp1 => ''); -- DEFAULT NULL
END;
请注意,在Toad for Oracle中,您甚至为声明为DEFAULT NULL
的参数提供了值(这不是问题)。
如果查看参数列表,您会看到您为arg1
,arg
,empti
,out
和{{1}提供了绑定}。您将这些位置匹配如下:
p
Oracle抱怨参数数量不匹配,这是因为您将引用游标参数声明为a_cursor => :c -- you created the OracleParameter as 'p', not 'c'
return_value => :out
a_type => :arg
a_time => :empti
a_id => :arg1
a_arg1 => :empti
a_from => :empti
a_gl2 => :empti
a_arg2 => :empti
a_temp1 => :empti
而不是p
。您需要将c
更新为OracleParamter
的名称,或者将正在执行的PL / SQL更改为c
以获取第一个参数。
答案 1 :(得分:1)
您无需将out光标指定为参数
其他明智的尝试以下代码
object[] parameters = {
new OracleParameter("arg1", arg1),
new OracleParameter("arg", "arg"),
new OracleParameter("empti", ""),
new OracleParameter("return_value", OracleDbType.Varchar2, ParameterDirection.Output),
new OracleParameter("a_cursor", OracleDbType.RefCursor, ParameterDirection.Output)
};
const string sql = "BEGIN package.my_procedure(:a_cursor, :return_value, :arg, :empti, :arg1 , :empti, :empti, :empti, :empti, :empti); END;";
res = _projectRepository.ExecuteStoredProcedure(sql, parameters);