oracle 遊標總結

for循環遊標


DECLARE
CURSOR C_EMP IS SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE JOB = 'MANAGER';
V_ROW C_EMP%ROWTYPE;
BEGIN
  FOR V_ROW IN C_EMP LOOP
    DBMS_OUTPUT.put_line(V_ROW.EMPNO || '-' || V_ROW.ENAME || '-' || V_ROW.JOB || '-' || V_ROW.SAL);
  END LOOP;
END;

或者

DECLARE
CURSOR C_EMP IS SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE JOB = 'MANAGER';
V_ROW EMP%ROWTYPE;
BEGIN
  FOR V_ROW IN C_EMP LOOP
    DBMS_OUTPUT.put_line(V_ROW.EMPNO || '-' || V_ROW.ENAME || '-' || V_ROW.JOB || '-' || V_ROW.SAL);
  END LOOP;
END;

或者

DECLARE
CURSOR C_EMP IS SELECT * FROM EMP;
V_ROW EMP%ROWTYPE;
BEGIN
  FOR V_ROW IN C_EMP LOOP
    DBMS_OUTPUT.put_line(V_ROW.EMPNO || '-' || V_ROW.ENAME || '-' || V_ROW.JOB || '-' || V_ROW.SAL);
  END LOOP;
END;


fetch遊標


DECLARE
CURSOR C_EMP IS SELECT * FROM EMP;
V_ROW EMP%ROWTYPE;
BEGIN
  OPEN C_EMP;
  LOOP
    FETCH C_EMP INTO V_ROW;
    EXIT WHEN C_EMP%NOTFOUND;
    DBMS_OUTPUT.put_line(V_ROW.EMPNO || '-' || V_ROW.ENAME || '-' || V_ROW.JOB || '-' || V_ROW.SAL);
  END LOOP;
  CLOSE C_EMP;
END;

隱式遊標


BEGIN
  UPDATE EMP SET ENAME = 'SMITH' WHERE EMPNO = 7369;
  COMMIT;
  DBMS_OUTPUT.put_line('SQL%ROWCOUNT = ' || SQL%ROWCOUNT);
  IF SQL%ISOPEN THEN
    DBMS_OUTPUT.put_line('SQL%ISOPEN');
  ELSE
    DBMS_OUTPUT.put_line('NOT SQL%ISOPEN');
  END IF;
  IF SQL%FOUND THEN
    DBMS_OUTPUT.put_line('SQL%FOUND');
  ELSE
    DBMS_OUTPUT.put_line('NOT SQL%FOUND');
  END IF;
  IF SQL%NOTFOUND THEN
    DBMS_OUTPUT.put_line('SQL%NOTFOUND');
  ELSE
    DBMS_OUTPUT.put_line('NOT SQL%NOTFOUND');
  END IF;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.put_line('NO_DATA_FOUND');
    WHEN TOO_MANY_ROWS THEN
      DBMS_OUTPUT.put_line('TOO_MANY_ROWS');
END;


while循環遊標


DECLARE
CURSOR C_EMP IS SELECT * FROM EMP;
V_ROW EMP%ROWTYPE;
BEGIN
  OPEN C_EMP;
  FETCH C_EMP INTO V_ROW;
  WHILE C_EMP%FOUND LOOP
    DBMS_OUTPUT.put_line(V_ROW.EMPNO || '-' || V_ROW.ENAME || '-' || V_ROW.JOB || '-' || V_ROW.SAL);
    FETCH C_EMP INTO V_ROW;
  END LOOP;
  CLOSE C_EMP;
END;

參數遊標


DECLARE
CURSOR C_EMP(P_EMPNO NUMBER) IS SELECT EMPNO, ENAME, JOB, SAL FROM EMP WHERE EMPNO = P_EMPNO;
V_ROW EMP%ROWTYPE;
BEGIN
  FOR V_ROW IN C_EMP(7369) LOOP
    DBMS_OUTPUT.put_line(V_ROW.EMPNO||V_ROW.ENAME||V_ROW.SAL);
  END LOOP;
END;

更新遊標

 

CREATE TABLE EMP1 AS SELECT * FROM EMP;

 

DECLARE
CURSOR C_EMP IS
SELECT E.EMPNO, E.ENAME, E.JOB, E.SAL, D.DEPTNO
FROM EMP1 E, DEPT D
WHERE E.DEPTNO = D.DEPTNO FOR UPDATE OF E.DEPTNO;
V_ROW EMP1%ROWTYPE;
V_SAL EMP1.SAL%TYPE;
BEGIN
  FOR V_ROW IN C_EMP LOOP
    IF V_ROW.SAL < 1500 THEN
      V_SAL := V_ROW.SAL * 1.2;
    ELSIF V_ROW.SAL < 2000 THEN
      V_SAL := V_ROW.SAL * 1.5;
    ELSIF V_ROW.SAL < 3000 THEN
      V_SAL := V_ROW.SAL * 2;
    END IF;
    UPDATE EMP1 SET SAL=V_SAL WHERE CURRENT OF C_EMP;
  END LOOP;
  COMMIT;
END;


鎖住E表中滿足條件的行。


或者


DECLARE
CURSOR C_EMP IS SELECT EMPNO, ENAME, JOB, SAL FROM EMP1 FOR UPDATE;
V_ROW EMP1%ROWTYPE;
V_SAL EMP1.SAL%TYPE;
BEGIN
  FOR V_ROW IN C_EMP LOOP
    IF V_ROW.SAL < 1500 THEN
      V_SAL := V_ROW.SAL * 1.2;
    ELSIF V_ROW.SAL < 2000 THEN
      V_SAL := V_ROW.SAL * 1.5;
    ELSIF V_ROW.SAL < 3000 THEN
      V_SAL := V_ROW.SAL * 2;
    END IF;
    UPDATE EMP1 SET SAL=V_SAL WHERE CURRENT OF C_EMP;
  END LOOP;
  COMMIT;
END;

鎖住所有行。


或者


DECLARE
CURSOR C_EMP IS SELECT EMPNO, ENAME, JOB, SAL FROM EMP1 FOR UPDATE NOWAIT;
V_ROW EMP1%ROWTYPE;
V_SAL EMP1.SAL%TYPE;
BEGIN
  FOR V_ROW IN C_EMP LOOP
    IF V_ROW.SAL < 1500 THEN
      V_SAL := V_ROW.SAL * 1.2;
    ELSIF V_ROW.SAL < 2000 THEN
      V_SAL := V_ROW.SAL * 1.5;
    ELSIF V_ROW.SAL < 3000 THEN
      V_SAL := V_ROW.SAL * 2;
    END IF;
    UPDATE EMP1 SET SAL=V_SAL WHERE CURRENT OF C_EMP;
  END LOOP;
  COMMIT;
END;

默認情況下當前會話要一直等待對方釋放鎖,使用nowait子句可以避免等待鎖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章