Oracle PL/SQL 引用游标如何

Posted

技术标签:

【中文标题】Oracle PL/SQL 引用游标如何【英文标题】:Oracle PL/SQL reference cursor how to 【发布时间】:2012-02-16 02:24:33 【问题描述】:

我正在尝试创建一个使用引用的 pl/sql 块。基本上,这就是我到目前为止所得到的。它们都作为单独的光标工作。我发现参考文献有点困难。我需要的是列出部门名称,然后转到emp_cursor 并列出部门_id = 外部光标部门_id 中的所有员工。

set serveroutput on 
declare
  cursor dept_cursor is 
    select department_id, department_name
    from departments 
    where department_id < 100;
    dep_id departments.department_id%type;
    dep_name departments.department_name%type;

    cursor emp_cursor is 
      select last_name, job_id, hire_date, salary
      from employees 
      where employee_id < 120 and department_id =/*Need reference from deptartmens.departments_id*/department_id;
      emp_ln employees.last_name%type;
      emp_jid employees.job_id%type;
      emp_hd employees.hire_date%type;
      emp_sal employees.salary%type;

begin
    for rec_dept in dept_cursor loop
      dbms_output.put_line('Department Number: '||rec_dept.department_id|| '   Department Name: ' || rec_dept.department_name);
      dbms_output.put_line('---------------------------------------------');
      for rec_emp in emp_cursor loop
        dbms_output.put_line(rec_emp.last_name||'   ' || rec_emp.job_id ||'   ' || rec_emp.hire_date ||'   '|| rec_emp.salary);
      end loop;
      dbms_output.put_line('---------------------------------------------');
    end loop;

end ;

例如,一些输出看起来像这样。

Department Number : 10  Department Name : Administration
----------------------------------------------------------------------------------------
Department Number : 20  Department Name : Marketing
----------------------------------------------------------------------------------------
Department Number : 30  Department Name : Purchasing
Raphaely    PU_MAN   07-DEC-94   11000
Khoo    PU_CLERK   18-MAY-95   3100
Baida    PU_CLERK   24-DEC-97   2900
Tobias    PU_CLERK   24-JUL-97   2800
Himuro    PU_CLERK   15-NOV-98   2600
Colmenares    PU_CLERK   10-AUG-99   2500
----------------------------------------------------------------------------------------

【问题讨论】:

【参考方案1】:

你需要的是一个游标变量:

cursor emp_cursor ( v_dept_id number ) is 
  select last_name, job_id, hire_date, salary
  from employees 
  where employee_id < 120 and department_id = v_dept_id;

然后:

for rec_emp in emp_cursor loop

变成:

for rec_emp in emp_cursor(rec_dept.department_id) loop

【讨论】:

【参考方案2】:

您可以将EMP_CURSOR 声明为参数化游标。类似的东西

declare
  cursor dept_cursor is
    select department_id, department_name
    from departments
    where department_id < 100;
    dep_id departments.department_id%type;
    dep_name departments.department_name%type;
  cursor emp_cursor( p_department_id IN NUMBER ) is
    select last_name, job_id, hire_date, salary
    from employees
    where employee_id < 120
      and department_id = p_department_id;
  emp_ln employees.last_name%type;
  emp_jid employees.job_id%type;
  emp_hd employees.hire_date%type;
  emp_sal employees.salary%type;
begin
  for rec_dept in dept_cursor loop
    dbms_output.put_line('Department Number: '||rec_dept.department_id|| '   Department Name: ' || rec_dept.department_name);
    dbms_output.put_line('---------------------------------------------');
    for rec_emp in emp_cursor( rec_dept.department_id ) loop
      dbms_output.put_line(rec_emp.last_name||'   ' || rec_emp.job_id ||'   ' || rec_emp.hire_date ||'   '|| rec_emp.salary);
    end loop;
    dbms_output.put_line('---------------------------------------------');
  end loop;
end ;

HR 架构中生成以下输出

Department Number: 10   Department Name: Administration
---------------------------------------------
---------------------------------------------
Department Number: 20   Department Name: Marketing
---------------------------------------------
---------------------------------------------
Department Number: 30   Department Name: Purchasing
---------------------------------------------
Raphaely   PU_MAN   07-DEC-02   11000
Khoo   PU_CLERK   18-MAY-03   3100
Baida   PU_CLERK   24-DEC-05   2900
Tobias   PU_CLERK   24-JUL-05   2800
Himuro   PU_CLERK   15-NOV-06   2600
Colmenares   PU_CLERK   10-AUG-07   2500
---------------------------------------------
Department Number: 40   Department Name: Human Resources
---------------------------------------------
---------------------------------------------
Department Number: 50   Department Name: Shipping
---------------------------------------------
---------------------------------------------
Department Number: 60   Department Name: IT
---------------------------------------------
Hunold   IT_PROG   03-JAN-06   9000
Ernst   IT_PROG   21-MAY-07   6000
Austin   IT_PROG   25-JUN-05   4800
Pataballa   IT_PROG   05-FEB-06   4800
Lorentz   IT_PROG   07-FEB-07   4200
---------------------------------------------
Department Number: 70   Department Name: Public Relations
---------------------------------------------
---------------------------------------------
Department Number: 80   Department Name: Sales
---------------------------------------------
---------------------------------------------
Department Number: 90   Department Name: Executive
---------------------------------------------
King   AD_PRES   17-JUN-03   24000
Kochhar   AD_VP   21-SEP-05   17000
De Haan   AD_VP   13-JAN-01   17000
---------------------------------------------

现在,从性能的角度来看,连接这两个表会比在 PL/SQL 中编写自己的嵌套循环要好得多。

【讨论】:

以上是关于Oracle PL/SQL 引用游标如何的主要内容,如果未能解决你的问题,请参考以下文章

Oracle PL SQL:比较两个存储过程返回的引用游标结果

如何使用Oracle的游标?

Oracle_PL/SQL 游标

如何在 Oracle PL/SQL 过程的开始部分之后声明游标

Oracle游标使用总结

oracle 游标是做啥用的