【发布时间】:2019-12-23 04:10:11
【问题描述】:
我有这个 C# 代码来调用 Oracle 存储过程:
using (OracleConnection oracleConnection = new OracleConnection(connectionString))
{
oracleConnection.Open();
OracleCommand oracleCommand = new OracleCommand();
oracleCommand.Parameters.Add(new OracleParameter
{
ParameterName = "eventids",
Direction = ParameterDirection.Input,
CollectionType = OracleCollectionType.PLSQLAssociativeArray,
Value = new string[] { "Test1", "Test2" },
Size = 2,
UdtTypeName = "T_STRING_TAB"
});
oracleCommand.Parameters.Add("p_cursor", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
oracleCommand.Connection = oracleConnection;
oracleCommand.CommandText = "spTest";
oracleCommand.CommandType = CommandType.StoredProcedure;
using (OracleDataReader oracleDataReader = oracleCommand.ExecuteReader())
{
while (oracleDataReader.Read())
{
int fieldCount = oracleDataReader.FieldCount;
string s = oracleDataReader.GetString(0);
}
}
}
我在数据库中有这个:
create or replace noneditionable package pp is
type t_string_tab is table of varchar2(260) index by binary_integer;
end;
create or replace noneditionable procedure sptest(
eventids in pp.t_string_tab,
p_cursor in out sys_refcursor)
as
begin
open p_cursor for
select p.column_value, 'Test1', 'Test2' from table(eventids) p;
end;
当我从代码中调用此过程时,出现以下错误:
Oracle.ManagedDataAccess.Client.OracleException:
ORA-21700: 对象不存在或被标记为删除
ORA-06512:在“PPUSER.SPGETMETADATA”,第 6 行 ORA-06512:在第 1 行'
这似乎与无法从存储过程访问的 T_STRING_TAB 类型有关?
即使我将存储过程放在 PP 包中并在代码中调用 PP.spTest,也会出现此错误。我还尝试在代码中使用 PP.T_STRING_TAB 作为 UdtTypeName,但这不起作用。我无法将类型设为全局,否则会出现以下错误:
PLS-00355:在此上下文中不允许使用 PL/SQL 表
请注意,我添加了一个新用户,这可能与权限有关吗?
我不确定自己做错了什么 - 我不是 Oracle 专家!
这个问题来自How to pass an array of strings from C# to an Oracle stored procedure。
【问题讨论】:
-
在这个网站 (dbtricks.com/?p=216 ) 中,它建议授予用户执行该类型的权限。你试过吗?
-
这是一个在包中定义的 PL/SQL 关联数组,因此需要在包上执行。
-
没有类型
t_string_tab。只有pp.t_string_type。我不懂 C#,所以无法判断赋值是否正确,但对 PL/SQL 类型和 SQL 类型之间的这种类型转换的支持高度依赖于版本。您的 Oracle 版本是多少? -
我试图授予对包的执行权限(应该做类型),但没有奏效。我试图将 sp 添加到包中,但这也不起作用。 Oracle 版本是 OraDB18Home1。
-
如果您从实际提供的值中选择数据作为输入,那将毫无意义。如果您只想将
string[]转换为DataReader或DataTable,则无需为此调用Oracle。