繁体   English   中英

从Oracle PL / SQL匿名块填充C#DataTable

[英]Fill C# DataTable from Oracle PL/SQL Anonymous Block

我试图执行并将游标的结果返回到我的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循环内的索引进行访问。

我只能对数据库进行读取访问,因此无法创建函数,过程等。是否可以将新的主管数据写入此程序范围内的临时表(而不是变量)中,以便进行选择*从循环后的临时表中获取。 或以其他任何方式可以得到所需的东西。 谢谢!

我认为代替PLSQL块,您可以使用一个分层查询,如下所示:

select emp_id supervisor_id, last_name, root emp_id
  from (
    select t.*, 
           min(case when active_ind = 'Y' and root <> emp_id 
                    then lvl end) over (partition by root) mlvl
      from (
        select m.*, level lvl,
               connect_by_root(emp_id) root
          from mytable m
          connect by emp_id = prior supervisor_id 
          start with emp_id in (1, 2) ) t )
  where lvl = mlvl

子查询t创建主管树。 接下来使用min()函数,我正在搜索具有最低级别(最接近员工)并且活跃的人。

测试数据:

create table myTable (emp_id number(3), active_ind varchar2(1),  
                      last_name varchar(10), supervisor_id number(3));

insert into mytable values (1, 'Y', 'Brown', 3);
insert into mytable values (2, 'Y', 'Smith', 4);
insert into mytable values (3, 'Y', 'Adams', 6);
insert into mytable values (4, 'N', 'Novak', 5);
insert into mytable values (5, 'Y', 'King',  null);
insert into mytable values (6, 'Y', 'Jones',  null);

输出:

SUPERVISOR_ID  LAST_NAME  EMP_ID
-------------  ---------  ------
3              Adams           1
5              King            2

编辑:Oracle 11和递归CTE版本:

with t (root, id, act, name, sid, stop) as (
  select emp_id, emp_id, active_ind, last_name, supervisor_id, 0
    from mytable where emp_id in (1, 2)
  union all 
  select t.root, m.emp_id, m.active_ind, m.last_name, m.supervisor_id, 
    case when m.active_ind = 'Y' then 1 else 0 end 
    from t join mytable m on m.emp_id = t.sid and t.stop = 0
  )
select * from t where stop = 1

如果出现“周期”问题,请使用CYCLE id SET cycle TO 1 DEFAULT 0 ,如此处所述: 递归子查询分解

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM