C# 如何从.NET前端在Oracle中使用用户定义的数据类型参数执行Oracle存储过程
我使用Oracle作为后端,C#作为前端 Oracle包声明如下:C# 如何从.NET前端在Oracle中使用用户定义的数据类型参数执行Oracle存储过程,c#,oracle,odp.net,C#,Oracle,Odp.net,我使用Oracle作为后端,C#作为前端 Oracle包声明如下: CREATE OR REPLACE PACKAGE SamplePackage IS TYPE t_number IS TABLE OF NUMBER INDEX BY PLS_INTEGER; PROCEDURE SampleProc(run_no IN t_number, Id IN t_number); END; CREATE OR REPLACE PACKAGE BODY SamplePackage IS
CREATE OR REPLACE PACKAGE SamplePackage IS
TYPE t_number IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
PROCEDURE SampleProc(run_no IN t_number, Id IN t_number);
END;
CREATE OR REPLACE PACKAGE BODY SamplePackage IS
PROCEDURE SampleProc(run_no IN t_number, Id IN t_number) IS
l_cnt NUMBER := 0;
BEGIN
FOR i IN 1 .. Id.count
LOOP
INSERT INTO SampleSchema.SampleTable
(run_no,
Id)
VALUES
(run_no(i),
Id(i));
-- commit every 1000 rows
l_cnt := l_cnt + 1;
IF (MOD(l_cnt,
1000) = 0) THEN
COMMIT;
END IF;
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,
'SamplePackage.SampleProc: ' || SQLERRM || dbms_utility.format_error_backtrace);
END SampleProc;
END;
string ConnectionString = ConfigurationManager.ConnectionStrings["oracleConnection"].ConnectionString.ToString();
using (var connection = new OracleConnection(ConnectionString))
{
connection.Open();
double[] run_no = new double[2];
double[] Id = new double[2];
run_no[0] = 10;
run_no[1] = 12;
Id[0] = 100;
Id[1] = 120;
OracleParameter ora_run_no = new OracleParameter();
ora_run_no.ParameterName = "run_no";
ora_run_no.OracleDbType = OracleDbType.Double;
ora_run_no.Direction = ParameterDirection.Input;
ora_run_no.UdtTypeName = "t_number";
ora_run_no.Value = run_no;
OracleParameter ora_p_quote_id = new OracleParameter();
ora_Id.ParameterName = "Id";
ora_Id.OracleDbType = OracleDbType.Double;
ora_Id.Direction = ParameterDirection.Input;
ora_Id.UdtTypeName = "t_number";
ora_Id.Value = Id;
OracleCommand cmdInsert = new OracleCommand();
cmdInsert.Connection = connection;
cmdInsert.CommandType = CommandType.StoredProcedure;
cmdInsert.CommandText = "SampleSchema.SamplePackage.SampleProc";
cmdInsert.BindByName = true;
cmdInsert.ArrayBindCount = Id.Length;
cmdInsert.Parameters.Add(ora_run_no);
cmdInsert.Parameters.Add(ora_Id);
cmdInsert.ExecuteNonQuery();
}
前端C#代码如下:
CREATE OR REPLACE PACKAGE SamplePackage IS
TYPE t_number IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
PROCEDURE SampleProc(run_no IN t_number, Id IN t_number);
END;
CREATE OR REPLACE PACKAGE BODY SamplePackage IS
PROCEDURE SampleProc(run_no IN t_number, Id IN t_number) IS
l_cnt NUMBER := 0;
BEGIN
FOR i IN 1 .. Id.count
LOOP
INSERT INTO SampleSchema.SampleTable
(run_no,
Id)
VALUES
(run_no(i),
Id(i));
-- commit every 1000 rows
l_cnt := l_cnt + 1;
IF (MOD(l_cnt,
1000) = 0) THEN
COMMIT;
END IF;
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,
'SamplePackage.SampleProc: ' || SQLERRM || dbms_utility.format_error_backtrace);
END SampleProc;
END;
string ConnectionString = ConfigurationManager.ConnectionStrings["oracleConnection"].ConnectionString.ToString();
using (var connection = new OracleConnection(ConnectionString))
{
connection.Open();
double[] run_no = new double[2];
double[] Id = new double[2];
run_no[0] = 10;
run_no[1] = 12;
Id[0] = 100;
Id[1] = 120;
OracleParameter ora_run_no = new OracleParameter();
ora_run_no.ParameterName = "run_no";
ora_run_no.OracleDbType = OracleDbType.Double;
ora_run_no.Direction = ParameterDirection.Input;
ora_run_no.UdtTypeName = "t_number";
ora_run_no.Value = run_no;
OracleParameter ora_p_quote_id = new OracleParameter();
ora_Id.ParameterName = "Id";
ora_Id.OracleDbType = OracleDbType.Double;
ora_Id.Direction = ParameterDirection.Input;
ora_Id.UdtTypeName = "t_number";
ora_Id.Value = Id;
OracleCommand cmdInsert = new OracleCommand();
cmdInsert.Connection = connection;
cmdInsert.CommandType = CommandType.StoredProcedure;
cmdInsert.CommandText = "SampleSchema.SamplePackage.SampleProc";
cmdInsert.BindByName = true;
cmdInsert.ArrayBindCount = Id.Length;
cmdInsert.Parameters.Add(ora_run_no);
cmdInsert.Parameters.Add(ora_Id);
cmdInsert.ExecuteNonQuery();
}
这里有些混乱。当我执行.NET代码时,它在ExecuteNonQuery
处抛出错误,如下所示
ORA-06550:第1行第7列:PLS-00306:调用“SAMPLEPROC”时参数的数量或类型错误 ORA-06550:第1行第7列:
PL/SQL:忽略语句
在Oracle后端,我使用的是
t\u number
用户定义的数据类型。我唯一需要知道的是如何将其作为数组处理并从C#成功执行。我对您正在使用的工具一无所知,但是-由于在包中声明了类型,我想说:
ora_Id.UdtTypeName = "t_number";
应该是
ora_Id.UdtTypeName = "SampleSchema.SamplePackage.t_number";
就像你在程序中使用的一样
除此之外,由于您使用的类型是数字表,您可以尝试使用Oracle的内置类型:
sys.odcinumberlist
。要成功执行,我是否需要为这两个字段分别创建临时表并更改UdtTypeName
或当前double[]
数组工作?因为使用sys.odcinumberlist
修改包和过程需要很长的过程,所以由其他团队处理。它仍然抛出相同的错误;正如我所说,我不知道你使用的工具,所以我不能对此发表评论。我希望你能设法让它工作。我正在使用ODP.NET
来实现这一点,但我仍然被卡住了。我能够成功地使用sys.odcinumberlist
。但是我需要它来做你的电话号码。当我将ora_Id.UdtTypeName
指定为t_number
时,它无法识别。出路是什么?