【发布时间】:2017-06-19 14:46:20
【问题描述】:
我正在尝试执行光标的结果并将其返回到我的 C# 程序。以下是我的代码:
OracleCommand cmd = new OracleCommand();
cmd.CommandText = @"
declare
varEmpID myTable.emp_id%type;
varSupID myTable.supervisor_id%type;
varNewSupID myTable.supervisor_id%type;
varSupActive myTable.active_ind%type;
Cursor C1 is(
select emp_id,active_ind,supervisor_id
from myTable where emp_id in
('1','2')) order by emp_id;
begin
Open C1;
LOOP
FETCH C1 INTO varEmpID,varSupActive,varSupID;
EXIT WHEN C1%NOTFOUND;
while (varSupActive<>'Y') loop
select m1.supervisor_id, m2.Active_Ind
into varNewSupID,varSupActive
from myTable m1, myTable m2
where m1.supervisor_id = m2.emp_id and m1.emp_id = varSupID;
varSupID := varNewSupID;
end loop;
open :rc1 for select sup.emp_id, sup.FIRST_NAME,sup.LAST_NAME
into varEmpID,varFirstName,varLastName
from myTable sup
where emp_id = varSupID;
END LOOP;
CLOSE C1;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
";
cmd.BindByName = true;
cmd.Parameters.Add("rc1", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
using (cmd.Connection = new OracleConnection(strCon))
{
cmd.Connection.Open();
var reader = cmd.ExecuteReader();
OracleDataAdapter da = new OracleDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
}
光标的目的是为给定的一组用户找到一个活跃的主管。如果我的表中用户的主管处于非活动状态,我需要在层次结构中上升,直到找到一个活动的主管。还有一些我在这里删除的条件,但我想说的是,我认为这不能使用单个 SQL 语句来实现。
很明显,我没有让所有新的主管都使用 rc1 游标,因为它在循环中并且被覆盖了。所以我的 C# 输出只给了我最后一个主管。我尝试创建表类型数组,但即使这样我也必须在 for 循环中使用索引来访问。
我只有对数据库的读取权限,所以我不能创建函数、过程等。有没有办法可以将新的主管数据写入该程序范围内的临时表而不是变量,这样我就可以在循环后从该临时表中选择 *。或者任何其他方式我可以得到我需要的东西。谢谢!
【问题讨论】:
-
从未尝试从 .NET 执行匿名块。通常我会创建一个流水线函数来将数据从 Oracle 传递到 .NET。见psoug.org/reference/pipelined.html
-
@PaulStearns 我不能也不应该在数据库中创建函数。
-
抱歉错过了只读位。这是您需要的程序,还是已简化?我问的原因是,您可能会使用“连接方式”语法并能够将所有内容放入单个查询中。 docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm
标签: c# oracle plsql cursor odp.net