在SQL -oracle中使用游标内的游标

时间:2014-08-03 23:40:56

标签: sql oracle

我正在网上查看我是否可以找到一个示例,说明游标(在游标中)如何用于2个表中我想要的结果但没有成功。所以我想知道是否有人可以指出我的例子或帮助我使用我的代码。

数据:来自2个表

DEPARTMENT_ID DEPARTMENT_NAME    
------------- --------------------
           10 ACCOUNTING           
           50 EXECUTIVE            
           40 IT                   
           60 MARKETING            
           20 RESEARCH             
           30 SALES                

选择了6行

EMPLOYEE_ID EMPLOYEE_NAME            SALARY DEPARTMENT_ID    MAX_SAL   MAX75SAL
----------- -------------------- ---------- ------------- ---------- ----------
       8000 BREWSTER                   2500                     2500       1875 
       7603 CLARK                      4000            50       5000       3750 
       7900 FISHER                     3000            30       3000       2250 
       7921 JACKSON                    2500            30       3000       2250 
       7566 JONES                      3000            10       3000       2250 
       7596 JOST                       4500            50       5000       3750 
       7839 KING                       5000            50       5000       3750 
       7944 LEE                        2400            20       3000       2250 
       7788 SCOTT                      2500            40       2900       2175 
       7910 SMITH                      2900            40       2900       2175 
       7886 STEEL                      2500            10       3000       2250 
       7610 WILSON                     3000            20       3000       2250 
       7999 WOLFE                      2500            20       3000       2250

起初我得到了这个结果:

ACCOUNTING              3000            2250      JONES
ACCOUNTING              3000            2250      STEEL
EXECUTIVE               5000            3750      CLARK
EXECUTIVE               5000            3750       JOST
EXECUTIVE               5000            3750       KING
IT                      2900            2175      SCOTT
IT                      2900            2175      SMITH
RESEARCH                3000            2250        LEE
RESEARCH                3000            2250     WILSON
RESEARCH                3000            2250      WOLFE
SALES                   3000            2250     FISHER
SALES                   3000            2250    JACKSON
N/A                     2500            1875   BREWSTER

但是我需要它们像:

ACCOUNTING              3000            2250      JONES STEEL
EXECUTIVE               5000            3750      CLARK JOST KING
IT                      2900            2175      SCOTT SMITH
RESEARCH                3000            2250        LEE WILSON WOLFE
SALES                   3000            2250     FISHER JACKSON

每个部门名称只会产生一行,但最后会有符合条件的员工姓名。

我的代码:

DECLARE
-- First cursor 
CURSOR c_get_dept IS
        SELECT      department_id, department_name 
    FROM            department
ORDER BY        department_name;

-- Second cursor 
CURSOR c_get_emp (p_dept_id NUMBER) IS

select  z.employee_id, z.employee_name, z.salary, z.department_id,
max_sal,(z.max_sal *.75)  max75sal
from
(
SELECT employee_id, employee_name,salary,department_id, 
max(salary) over (partition by department_id) as max_sal
FROM        employee
ORDER BY employee_name
) z
WHERE salary > (max_sal*.75 )
order by z.employee_name;

v_flag NUMBER;
BEGIN
-- Open first cursor
FOR idx_1 IN c_get_dept LOOP
        v_flag := 0;
-- Open second cursor `
        FOR idx_2 IN c_get_emp(idx_1.department_id) LOOP
            IF v_flag = 0 THEN

DBMS_OUTPUT.PUT_LINE(idx_1.department_name || '   ' || idx_2.max_sal ||
                '   ' || idx_2.max75sal || '   ' || idx_2.EMPLOYEE_NAME);
                v_flag := 0;
            END IF;
        END LOOP;
IF v_flag = 0 THEN
        DBMS_OUTPUT.PUT_LINE('  No output.');
    END IF;

 END LOOP;
 END;
谢谢你!

1 个答案:

答案 0 :(得分:1)

如果您正在使用Oracle 11.2,则可以使用LISTAGG功能(reference here)来帮助您尝试执行的操作。以下查询生成您要查找的结果:

SELECT d.DEPARTMENT_NAME,
       MAX(e.SALARY) AS MAX_SALARY,
       MAX(e.SALARY)*0.75 AS MAX75,
       LISTAGG(e.EMPLOYEE_NAME, ' ')
         WITHIN GROUP (ORDER BY d.DEPARTMENT_NAME) AS EMPLOYEES
  FROM DEPARTMENT d
  INNER JOIN EMPLOYEE e
    ON e.DEPARTMENT_ID = d.DEPARTMENT_ID
  GROUP BY d.DEPARTMENT_NAME
  ORDER BY d.DEPARTMENT_NAME

SQLFiddle here

如果这样做的目的是在PL / SQL块中使用多个游标,我建议尝试像下面那样简单的注意事项(注意和警告:未经测试的代码如下):

DECLARE
  nDepartment_max_salary  NUMBER;
  strEmployees            VARCHAR2(32767);
BEGIN
  FOR dept IN (SELECT *
                 FROM DEPARTMENT
                 ORDER BY DEPARTMENT_NAME)
  LOOP
    nDepartment_max_salary := 0;
    strEmployees := NULL;

    FOR emp IN (SELECT *
                  FROM EMPLOYEE e
                  WHERE e.DEPARTMENT_ID = dept.DEPARTMENT_ID)
    LOOP
      nDepartment_max_salary := GREATER(nDepartment_max_salary, emp.SALARY);
      strEmployees := strEmployees || emp.EMPLOYEE_NAME || ' ';
    END LOOP; -- emp

    DBMS_OUTPUT.PUT_LINE(dept.DEPARTMENT_NAME || '   ' ||
                         nDepartment_max_salary || '   ' ||
                         nDepartment_max_salaray * 0.75 || '   ' ||
                         strEmployees);
  END LOOP;  -- dept
END;

分享并享受。