在上一文中我们介绍了PLSQL中包创建方法,本文介绍在C#中调用包中存储函数和存储过程的方法,以上一文中我们封装到emp_pack包中的get_emp_func函数为例,我们介绍C#中调用该函数的方法。
首先,emp_pack包体的定义如下:
create or replace
package body emp_pack
as
function get_emp_func(p_dno dept.deptno%type) return sys_refcursor
as
v_cur sys_refcursor;
begin
open v_cur for select * from emp where deptno=p_dno;
return v_cur;
end;
procedure insert_emp(v_empno emp.empno%type,v_ename emp.ename%type,v_job emp.job%type,v_mgr emp.mgr%type,v_sal emp.sal%type,v_deptno emp.deptno%type)
as
v_count number;
begin
select count(*) into v_count from emp where empno=v_empno;
if v_count>0 then
raise_application_error(-20789,'增加失败,该部门已经存在');
else
insert into emp values(v_empno,v_ename,v_job,v_mgr,sysdate,v_sal,null,v_deptno);
end if;
commit;
exception
when others then
dbms_output.put_line('sqlerrm='||sqlerrm);
rollback;
end;
end;
我们包中对get_emp_func的定义是,该函数接收一个number型的部门号作为参数,返回emp表中查询到的参考游标。我们在C#中实现的效果是调用该函数,并获取到该游标,并读出游标管理的数据集数据。参照下面的代码:
try
{
OracleParameter[] parameters = {
new OracleParameter("ReturnValue", OracleDbType.RefCursor, 0, ParameterDirection.ReturnValue, true, 0, 0, "",DataRowVersion.Default, Convert.DBNull ),
new OracleParameter("p_dno", OracleDbType.Int32,1)
};
parameters[1].Value = deptno;
OracleCommand orc = conn.CreateCommand();
orc.CommandType = CommandType.StoredProcedure;
orc.CommandText = "EMP_PACK.GET_EMP_FUNC";
foreach (OracleParameter param in parameters)
orc.Parameters.Add(param);
orc.ExecuteNonQuery();
Oracle.ManagedDataAccess.Types.OracleRefCursor cur = parameters[0].Value as Oracle.ManagedDataAccess.Types.OracleRefCursor;
OracleDataReader reader = cur.GetDataReader();
//第一种遍历方式
foreach (System.Data.Common.DbDataRecord obj in reader)
{
object[] values = new object[obj.FieldCount];
obj.GetValues(values);
}
//第二种遍历方式
{
System.Collections.IEnumerator enumrator = reader.GetEnumerator();
enumrator.MoveNext();
System.Data.Common.DbDataRecord obj = enumrator.Current as System.Data.Common.DbDataRecord;
while (obj != null)
{
object[] values = new object[obj.FieldCount];
obj.GetValues(values);
enumrator.MoveNext();
obj = enumrator.Current as System.Data.Common.DbDataRecord;
}
}
}
catch (System.Exception ex)
{
}
(1)和调用普通的存储函数类似,我们还是把函数的返回值放到parameters的第一个元素中,其第二个元素开始放置函数所需要的参数。
(2) 第10行,传入调用的函数名称,这里需要加上我们定义的包的名称。
(3)第15、16行是获取到了该存储函数返回的游标类型,我们需要读出该游标管理的数据集,在第16行获取该游标的OracleDataReader 对象,接下来的操作就是通过该对象;来获取数据。
(4)OracleDataReader 对象继承了IEnumerator,所以我们后面列举了两种方式来对其进行遍历,一种是用foreach,另一种是利用其继承自IEnumerator的GetEnumerator()方法等等,通过遍历我们可以获取到该游标对象所管理的数据集数据。