协助PL / SQL游标

时间:2015-11-18 03:39:34

标签: plsql cursor

我有2个表格,另外还有第三个表格会将数据输入其中。

表是:

SQL> select *
 2  from paydata1;

IDNO NAME                      J     SALARY      PAYHR
---- ------------------------- - ---------- ----------
1111 Ann French                S      75000          0
2222 Robert Costa              H          0         45
3333 Linda Ames                H          0         50
4444 Scott Brooks              S      78000          0
5555 Susan Ash                 S      57000          0
6666 James Smith               S      55000          0
7777 Mary Jones                H          0         36
8888 John Morse                H          0         39

SQL> select *
 2  from paytran1;

IDNO PRO    HOURSWK
---- --- ----------
1111 123         20
1111 456         10
1111 789         15
2222 123         17
2222 456         24
2222 789         20
3333 123         20
3333 789         20
4444 123         10
4444 456         28
4444 789          5
5555 456         40
6666 456         44
7777 456         30
7777 789         15
8888 123         10
8888 456         25
8888 789          5

问题是:编写PL / SQL程序以使用游标读取文件,并写出每个员工的总工作时间。

我的pl / sql代码是:

SET SERVEROUTPUT ON
DECLARE
  v_idno      paydata1.idno%TYPE;
  v_name      paydata1.name%TYPE;
  v_idno1     paytran1.idno%TYPE;
  v_hourswk   paytran1.hourswk%TYPE;  
  CURSOR paydata1_cursor IS
     SELECT idno, name FROM paydata1
     ORDER BY idno;
  CURSOR paytran1_cursor IS
     SELECT idno, hourswk FROM paytran1 
     WHERE v_idno1 = idno
     order BY idno;
  BEGIN
     OPEN paydata1_cursor;
     LOOP
       FETCH paydata1_cursor INTO v_idno, v_name;
       EXIT WHEN paydata1_cursor%NOTFOUND;
       IF paytran1_cursor%ISOPEN THEN
        CLOSE paytran1_cursor;
       END IF;
       OPEN paytran1_cursor;
       LOOP
         FETCH paytran1_cursor INTO v_idno1, v_hourswk;
         EXIT WHEN paytran1_cursor%NOTFOUND;
         END LOOP;
       INSERT into allinfo 
          VALUES(v_idno, v_name, v_hourswk);
      CLOSE paytran1_cursor;
     END LOOP;
     CLOSE paydata1_cursor;
END;
/
SET SERVEROUTPUT OFF

我的allinfo表结果是:

SQL> select *
  2  from allinfo;

IDNO EMPLOYEE             HOURS
---- --------------- ----------
1111 Ann French
2222 Robert Costa
3333 Linda Ames
4444 Scott Brooks
5555 Susan Ash
6666 James Smith
7777 Mary Jones
8888 John Morse

为什么小时组合并在allinfo表上显示idno和名称?

2 个答案:

答案 0 :(得分:2)

尝试将paytran1_cursor设为参数化游标:

CURSOR paytran1_cursor (p_idno1 paydata1.idno%TYPE) IS
     SELECT SUM(hourswk) FROM paytran1 -- already have idno; just sum hours
     WHERE p_idno1 = idno -- don't need to order by one value
[...]

-- sum() will return one row, so no need to loop
OPEN paytran1_cursor (v_idno1);
FETCH paytran1_cursor INTO v_hourswk;

(我认为这是Oracle语法。)

这里有几个问题。主要的一点是,当光标打开时,光标查询以编写运行。这意味着当您打开paytran1_cursor时,您正在查询当时 - v_idno1的当前值,即NULL。在这里使用参数化光标

  1. 确保传递到WHERE子句的值在范围内, 和
  2. 清楚地向读者明确表示您正在调整光标 查询来自光标外部的数据。
  3. 希望有所帮助。

答案 1 :(得分:0)

通过查看代码。我认为更好的方法是使方法纯粹是sql而不是使用PLSQL方法。我已经以可以实现它的方式复制了场景。我会这会帮助你。

INSERT INTO <TABLE>
SELECT A.IDNO,
  SUM(A.PSUM+B.HSWR)
FROM
  (SELECT PAYHR.IDNO,
    SUM(PAYHR.PAYHR) PSUM
  FROM
    (SELECT 111 AS IDNO,23 AS PAYHR FROM DUAL
    UNION ALL
    SELECT 111 AS IDNO,30 AS PAYHR FROM DUAL
    UNION ALL
    SELECT 112 AS IDNO,10 AS PAYHR FROM DUAL
    UNION ALL
    SELECT 112 AS IDNO,8 AS PAYHR FROM DUAL
    UNION ALL
    SELECT 112 AS IDNO,15 AS PAYHR FROM DUAL
    UNION ALL
    SELECT 113 AS IDNO,25 AS PAYHR FROM DUAL
    )PAYHR
  GROUP BY PAYHR.IDNO
  )A,
  (SELECT HSWRK.IDNO,
    SUM(HSWRK.HSWR) HSWR
  FROM
    ( SELECT 111 AS IDNO,10 HSWR FROM DUAL
    UNION ALL
    SELECT 111 AS IDNO,30 HSWR FROM DUAL
    UNION ALL
    SELECT 111 AS IDNO,15 HSWR FROM DUAL
    UNION ALL
    SELECT 111 AS IDNO,25 HSWR FROM DUAL
    UNION ALL
    SELECT 112 AS IDNO,10 HSWR FROM DUAL
    UNION ALL
    SELECT 112 AS IDNO,17 HSWR FROM DUAL
    UNION ALL
    SELECT 112 AS IDNO,40 HSWR FROM DUAL
    UNION ALL
    SELECT 113 AS IDNO,16 HSWR FROM DUAL
    )HSWRK
  GROUP BY HSWRK.IDNO
  )B
WHERE A.IDNO = B.IDNO
GROUP BY A.IDNO;