Oracle PL/SQL/Cursor/Cursor Open

Материал из SQL эксперт
Перейти к: навигация, поиск

An illegal location for a cursor.

   <source lang="sql">

SQL> SQL> CREATE TABLE lecturer (

 2    id               NUMBER(5) PRIMARY KEY,
 3    first_name       VARCHAR2(20),
 4    last_name        VARCHAR2(20),
 5    major            VARCHAR2(30),
 6    current_credits  NUMBER(3)
 7    );

Table created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10001, "Scott", "Lawson","Computer Science", 11);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major, current_credits)

 2                VALUES (10002, "Mar", "Wells","History", 4);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10003, "Jone", "Bliss","Computer Science", 8);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10004, "Man", "Kyte","Economics", 8);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10005, "Pat", "Poll","History", 4);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10006, "Tim", "Viper","History", 4);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10007, "Barbara", "Blues","Economics", 7);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10008, "David", "Large","Music", 4);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10009, "Chris", "Elegant","Nutrition", 8);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10010, "Rose", "Bond","Music", 7);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10011, "Rita", "Johnson","Nutrition", 8);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10012, "Sharon", "Clear","Computer Science", 3);

1 row created. SQL> SQL> SQL> DECLARE

 2    FUNCTION FormatName(p_FirstName IN VARCHAR2,
 3                        p_LastName IN VARCHAR2)
 4      RETURN VARCHAR2 IS
 5    BEGIN
 6      RETURN p_FirstName || " " || p_LastName;
 7    END FormatName;
 8
 9    CURSOR myAllLecturer IS
10      SELECT first_name, last_name
11        FROM lecturer;
12
13    v_FormattedName VARCHAR2(50);
14
15  BEGIN
16    NULL;
17  END;
18  /
 CURSOR myAllLecturer IS
 *

ERROR at line 9: ORA-06550: line 9, column 3: PLS-00103: Encountered the symbol "CURSOR" when expecting one of the following: begin function package pragma procedure form

SQL> SQL> drop table lecturer; Table dropped. SQL>

</source>
   
  


Cursor OPEN Example

   <source lang="sql">

SQL> SQL> SQL> SQL> CREATE TABLE place (

 2    room_id          NUMBER(5) PRIMARY KEY,
 3    building         VARCHAR2(15),
 4    room_number      NUMBER(4),
 5    number_seats     NUMBER(4),
 6    description      VARCHAR2(50)
 7    );

Table created. SQL> SQL> INSERT INTO place (room_id, building, room_number, number_seats, description)

 2             VALUES (20001, "Building 7", 201, 1000, "Large Lecture Hall");

1 row created. SQL> SQL> INSERT INTO place (room_id, building, room_number, number_seats, description)

 2             VALUES (20002, "Building 6", 101, 500, "Small Lecture Hall");

1 row created. SQL> SQL> INSERT INTO place (room_id, building, room_number, number_seats, description)

 2             VALUES (20003, "Building 6", 150, 50, "Discussion Room A");

1 row created. SQL> SQL> INSERT INTO place (room_id, building, room_number, number_seats, description)

 2             VALUES (20004, "Building 6", 160, 50, "Discussion Room B");

1 row created. SQL> SQL> INSERT INTO place (room_id, building, room_number, number_seats,description)

 2             VALUES (20005, "Building 6", 170, 50, "Discussion Room C");

1 row created. SQL> SQL> INSERT INTO place (room_id, building, room_number, number_seats, description)

 2             VALUES (20006, "Music Building", 100, 10, "Music Practice Room");

1 row created. SQL> SQL> INSERT INTO place (room_id, building, room_number, number_seats, description)

 2             VALUES (20007, "Music Building", 200, 1000, "Concert Room");

1 row created. SQL> SQL> INSERT INTO place (room_id, building, room_number, number_seats, description)

 2             VALUES (20008, "Building 7", 300, 75, "Discussion Room D");

1 row created. SQL> SQL> INSERT INTO place (room_id, building, room_number, number_seats,description)

 2             VALUES (20009, "Building 7", 310, 50, "Discussion Room E");

1 row created. SQL> SQL> SQL> CREATE TABLE session (

 2    department       CHAR(3),
 3    course           NUMBER(3),
 4    description      VARCHAR2(2000),
 5    max_lecturer     NUMBER(3),
 6    current_lecturer NUMBER(3),
 7    num_credits      NUMBER(1),
 8    room_id          NUMBER(5)
 9    );

Table created. SQL> SQL> INSERT INTO session(department, course, description, max_lecturer, current_lecturer, num_credits, room_id)

 2              VALUES ("HIS", 101, "History 101", 30, 11, 4, 20000);

1 row created. SQL> SQL> INSERT INTO session(department, course, description, max_lecturer, current_lecturer, num_credits, room_id)

 2              VALUES ("HIS", 301, "History 301", 30, 0, 4, 20004);

1 row created. SQL> SQL> INSERT INTO session(department, course, description, max_lecturer, current_lecturer, num_credits, room_id)

 2              VALUES ("CS", 101, "Computer Science 101", 50, 0, 4, 20001);

1 row created. SQL> SQL> INSERT INTO session(department, course, description, max_lecturer, current_lecturer, num_credits, room_id)

 2              VALUES ("ECN", 203, "Economics 203", 15, 0, 3, 20002);

1 row created. SQL> SQL> INSERT INTO session(department, course, description, max_lecturer, current_lecturer, num_credits, room_id)

 2              VALUES ("CS", 102, "Computer Science 102", 35, 3, 4, 20003);

1 row created. SQL> SQL> INSERT INTO session(department, course, description, max_lecturer, current_lecturer, num_credits, room_id)

 2              VALUES ("MUS", 410, "Music 410", 5, 4, 3, 20005);

1 row created. SQL> SQL> INSERT INTO session(department, course, description, max_lecturer, current_lecturer, num_credits, room_id)

 2              VALUES ("ECN", 101, "Economics 101", 50, 0, 4, 20007);

1 row created. SQL> SQL> INSERT INTO session(department, course, description, max_lecturer, current_lecturer, num_credits, room_id)

 2              VALUES ("NUT", 307, "Nutrition 307", 20, 2, 4, 20008);

1 row created. SQL> SQL> INSERT INTO session(department, course, description, max_lecturer, current_lecturer, num_credits, room_id)

 2              VALUES ("MUS", 100, "Music 100", 100, 0, 3, NULL);

1 row created. SQL> SQL> SQL> DECLARE

 2    v_RoomID      session.room_id%TYPE;
 3    v_Building    place.building%TYPE;
 4    v_Department  session.department%TYPE;
 5    v_Course      session.course%TYPE;
 6    CURSOR c_Buildings IS
 7      SELECT building
 8        from place, session
 9        where place.room_id = session.room_id
10        and department = v_Department
11        and course = v_Course;
12  BEGIN
13    v_Department := "HIS";
14    v_Course := 101;
15
16    OPEN c_Buildings;
17
18    v_Department := "XXX";
19    v_Course := -1;
20  END;
21  /

PL/SQL procedure successfully completed. SQL> SQL> drop table session; Table dropped. SQL> drop table place; Table dropped. SQL> SQL>

</source>
   
  


Open a cursor based on the result of row_number over partition by, order by

   <source lang="sql">

SQL> SQL> CREATE TABLE EMP (EMPNO NUMBER(4) NOT NULL,

 2                    ENAME VARCHAR2(10),
 3                    JOB VARCHAR2(9),
 4                    MGR NUMBER(4),
 5                    HIREDATE DATE,
 6                    SAL NUMBER(7, 2),
 7                    COMM NUMBER(7, 2),
 8                    DEPTNO NUMBER(2));

Table created. SQL> SQL> INSERT INTO EMP VALUES (7369, "SMITH", "CLERK", 7902, TO_DATE("17-DEC-1980", "DD-MON-YYYY"), 800, NULL, 20); 1 row created. SQL> INSERT INTO EMP VALUES (7499, "ALLEN", "SALESMAN", 7698, TO_DATE("20-FEB-1981", "DD-MON-YYYY"), 1600, 300, 30); 1 row created. SQL> INSERT INTO EMP VALUES (7521, "WARD", "SALESMAN", 7698, TO_DATE("22-FEB-1981", "DD-MON-YYYY"), 1250, 500, 30); 1 row created. SQL> INSERT INTO EMP VALUES (7566, "JONES", "MANAGER", 7839, TO_DATE("2-APR-1981", "DD-MON-YYYY"), 2975, NULL, 20); 1 row created. SQL> INSERT INTO EMP VALUES (7654, "MARTIN", "SALESMAN", 7698,TO_DATE("28-SEP-1981", "DD-MON-YYYY"), 1250, 1400, 30); 1 row created. SQL> INSERT INTO EMP VALUES (7698, "BLAKE", "MANAGER", 7839,TO_DATE("1-MAY-1981", "DD-MON-YYYY"), 2850, NULL, 30); 1 row created. SQL> INSERT INTO EMP VALUES (7782, "CLARK", "MANAGER", 7839,TO_DATE("9-JUN-1981", "DD-MON-YYYY"), 2450, NULL, 10); 1 row created. SQL> INSERT INTO EMP VALUES (7788, "SCOTT", "ANALYST", 7566,TO_DATE("09-DEC-1982", "DD-MON-YYYY"), 3000, NULL, 20); 1 row created. SQL> INSERT INTO EMP VALUES (7839, "KING", "PRESIDENT", NULL,TO_DATE("17-NOV-1981", "DD-MON-YYYY"), 5000, NULL, 10); 1 row created. SQL> INSERT INTO EMP VALUES (7844, "TURNER", "SALESMAN", 7698,TO_DATE("8-SEP-1981", "DD-MON-YYYY"), 1500, 0, 30); 1 row created. SQL> INSERT INTO EMP VALUES (7876, "ADAMS", "CLERK", 7788,TO_DATE("12-JAN-1983", "DD-MON-YYYY"), 1100, NULL, 20); 1 row created. SQL> INSERT INTO EMP VALUES (7900, "JAMES", "CLERK", 7698,TO_DATE("3-DEC-1981", "DD-MON-YYYY"), 950, NULL, 30); 1 row created. SQL> INSERT INTO EMP VALUES (7902, "FORD", "ANALYST", 7566,TO_DATE("3-DEC-1981", "DD-MON-YYYY"), 3000, NULL, 20); 1 row created. SQL> INSERT INTO EMP VALUES (7934, "MILLER", "CLERK", 7782,TO_DATE("23-JAN-1982", "DD-MON-YYYY"), 1300, NULL, 10); 1 row created. SQL> SQL> select * from emp;

  EMPNO ENAME      JOB            MGR HIREDATE       SAL     COMM DEPTNO

---------- --------- -------- --------- -------- -------- ------
7369.00 SMITH      CLERK      7902.00 17-DEC-80   800.00              20
7499.00 ALLEN      SALESMAN   7698.00 20-FEB-81  1600.00   300.00     30
7521.00 WARD       SALESMAN   7698.00 22-FEB-81  1250.00   500.00
7566.00 JONES      MANAGER    7839.00 02-APR-81  2975.00              20
7654.00 MARTIN     SALESMAN   7698.00 28-SEP-81  1250.00  1400.00     30
7698.00 BLAKE      MANAGER    7839.00 01-MAY-81  2850.00
7782.00 CLARK      MANAGER    7839.00 09-JUN-81  2450.00              10
  EMPNO ENAME      JOB            MGR HIREDATE       SAL     COMM DEPTNO

---------- --------- -------- --------- -------- -------- ------
7788.00 SCOTT      ANALYST    7566.00 09-DEC-82  3000.00              20
7839.00 KING       PRESIDENT          17-NOV-81  5000.00              10
7844.00 TURNER     SALESMAN   7698.00 08-SEP-81  1500.00      .00     30
7876.00 ADAMS      CLERK      7788.00 12-JAN-83  1100.00              20
7900.00 JAMES      CLERK      7698.00 03-DEC-81   950.00              30
  EMPNO ENAME      JOB            MGR HIREDATE       SAL     COMM DEPTNO

---------- --------- -------- --------- -------- -------- ------
7902.00 FORD       ANALYST    7566.00 03-DEC-81  3000.00              20
7934.00 MILLER     CLERK      7782.00 23-JAN-82  1300.00              10

14 rows selected. SQL> begin

 2      open :x for
 3      "select mgr,
 4              ename,
 5              row_number() over ( partition by mgr
 6                                  order by ename ) rn
 7         from emp";
 8  end;
 9  /

PL/SQL procedure successfully completed.

    MGR ENAME            RN

---------- --------
7566.00 FORD           1.00
7566.00 SCOTT          2.00
7698.00 ALLEN          1.00
7698.00 JAMES          2.00
7698.00 MARTIN         3.00
7698.00 TURNER         4.00
7698.00 WARD           5.00
7782.00 MILLER         1.00
7788.00 ADAMS          1.00
7839.00 BLAKE          1.00
7839.00 CLARK          2.00
    MGR ENAME            RN

---------- --------
7839.00 JONES          3.00
7902.00 SMITH          1.00
        KING           1.00

14 rows selected. SQL> SQL> drop table emp; Table dropped.

</source>
   
  


Open a cursor for read

   <source lang="sql">

SQL> SQL> -- create demo table SQL> create table Employee(

 2    ID                 VARCHAR2(4 BYTE)         NOT NULL,
 3    First_Name         VARCHAR2(10 BYTE),
 4    Last_Name          VARCHAR2(10 BYTE),
 5    Start_Date         DATE,
 6    End_Date           DATE,
 7    Salary             Number(8,2),
 8    City               VARCHAR2(10 BYTE),
 9    Description        VARCHAR2(15 BYTE)
10  )
11  /

Table created. SQL> SQL> -- prepare data SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)

 2               values ("01","Jason",    "Martin",  to_date("19960725","YYYYMMDD"), to_date("20060725","YYYYMMDD"), 1234.56, "Toronto",  "Programmer")
 3  /

1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)

 2                values("02","Alison",   "Mathews", to_date("19760321","YYYYMMDD"), to_date("19860221","YYYYMMDD"), 6661.78, "Vancouver","Tester")
 3  /

1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)

 2                values("03","James",    "Smith",   to_date("19781212","YYYYMMDD"), to_date("19900315","YYYYMMDD"), 6544.78, "Vancouver","Tester")
 3  /

1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)

 2                values("04","Celia",    "Rice",    to_date("19821024","YYYYMMDD"), to_date("19990421","YYYYMMDD"), 2344.78, "Vancouver","Manager")
 3  /

1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)

 2                values("05","Robert",   "Black",   to_date("19840115","YYYYMMDD"), to_date("19980808","YYYYMMDD"), 2334.78, "Vancouver","Tester")
 3  /

1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)

 2                values("06","Linda",    "Green",   to_date("19870730","YYYYMMDD"), to_date("19960104","YYYYMMDD"), 4322.78,"New York",  "Tester")
 3  /

1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)

 2                values("07","David",    "Larry",   to_date("19901231","YYYYMMDD"), to_date("19980212","YYYYMMDD"), 7897.78,"New York",  "Manager")
 3  /

1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)

 2                values("08","James",    "Cat",     to_date("19960917","YYYYMMDD"), to_date("20020415","YYYYMMDD"), 1232.78,"Vancouver", "Tester")
 3  /

1 row created. SQL> SQL> SQL> SQL> -- display data in the table SQL> select * from Employee

 2  /

ID FIRST_NAME LAST_NAME START_DAT END_DATE SALARY CITY DESCRIPTION


---------- ---------- --------- --------- ---------- ---------- ---------------

01 Jason Martin 25-JUL-96 25-JUL-06 1234.56 Toronto Programmer 02 Alison Mathews 21-MAR-76 21-FEB-86 6661.78 Vancouver Tester 03 James Smith 12-DEC-78 15-MAR-90 6544.78 Vancouver Tester 04 Celia Rice 24-OCT-82 21-APR-99 2344.78 Vancouver Manager 05 Robert Black 15-JAN-84 08-AUG-98 2334.78 Vancouver Tester 06 Linda Green 30-JUL-87 04-JAN-96 4322.78 New York Tester 07 David Larry 31-DEC-90 12-FEB-98 7897.78 New York Manager 08 James Cat 17-SEP-96 15-APR-02 1232.78 Vancouver Tester 8 rows selected. SQL> SQL> SQL> SQL> declare

 2      cursor employeeCursor
 3      is select e.first_name || " " || e.last_name name, e.salary
 4           from employee e;
 5
 6      name       varchar2(200);
 7      salary     number(9,2);
 8    begin
 9      for c1 in (select avg(e.salary) avg_salary
10                   from employee e) loop
11        dbms_output.put_line("average salary "||c1.avg_salary);
12      end loop;
13
14      open employeeCursor;
15      fetch employeeCursor into name, salary;
16
17      dbms_output.put_line(chr(13) || chr(13));
18      dbms_output.put_line("EmployeeS");
19      dbms_output.put_line("------------------------");
20
21      while employeeCursor%FOUND loop
22        dbms_output.put_line(name || " makes $" || salary);
23        fetch employeeCursor into name, salary;
24      end loop;
25      close employeeCursor;
26    end;
27    /

average salary 4071.7525 EmployeeS


Jason Martin makes $1234.56 Alison Mathews makes $6661.78 James Smith makes $6544.78 Celia Rice makes $2344.78 Robert Black makes $2334.78 Linda Green makes $4322.78 David Larry makes $7897.78 James Cat makes $1232.78 PL/SQL procedure successfully completed. SQL> SQL> SQL> SQL> SQL> SQL> -- clean the table SQL> drop table Employee

 2  /

Table dropped. SQL> SQL> SQL> SQL>

      </source>
   
  


Open cursor from a dynamic statement

   <source lang="sql">

SQL> SQL> CREATE TABLE MyTable(yourRow INTEGER, yourDesc VARCHAR2(50)); Table created. SQL> SQL> SET ECHO ON SQL> SET SERVEROUTPUT ON SQL> SQL> DECLARE

 2      TYPE your_cursor_type IS REF CURSOR;
 3      your_cursor  your_cursor_type;
 4
 5      TYPE dyn_record IS RECORD (
 6          yourrow    INTEGER,
 7          yourdesc   VARCHAR2(50)
 8          );
 9
10      dyn_rec dyn_record;
11
12      dynamic_select_stmt VARCHAR2(100);
13  BEGIN
14      dynamic_select_stmt := "SELECT yourrow, yourdesc FROM mytable";
15      dynamic_select_stmt := dynamic_select_stmt || " ORDER BY yourrow DESC";
16
17      OPEN your_cursor FOR dynamic_select_stmt;
18
19      LOOP
20          FETCH your_cursor
21              INTO dyn_rec;
22          EXIT WHEN your_cursor%NOTFOUND;
23
24          DBMS_OUTPUT.PUT_LINE(dyn_rec.yourrow || " " || dyn_rec.yourdesc);
25      END LOOP;
26      CLOSE your_cursor;
27  END;
28  /

PL/SQL procedure successfully completed. SQL> SQL> drop table mytable; Table dropped. SQL> SQL> --

</source>
   
  


ORA-6511 error: cursor already open

   <source lang="sql">

SQL> SQL> SQL> CREATE TABLE lecturer (

 2    id               NUMBER(5) PRIMARY KEY,
 3    first_name       VARCHAR2(20),
 4    last_name        VARCHAR2(20),
 5    major            VARCHAR2(30),
 6    current_credits  NUMBER(3)
 7    );

Table created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10001, "Scott", "Lawson","Computer Science", 11);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major, current_credits)

 2                VALUES (10002, "Mar", "Wells","History", 4);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10003, "Jone", "Bliss","Computer Science", 8);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10004, "Man", "Kyte","Economics", 8);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10005, "Pat", "Poll","History", 4);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10006, "Tim", "Viper","History", 4);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10007, "Barbara", "Blues","Economics", 7);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10008, "David", "Large","Music", 4);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10009, "Chris", "Elegant","Nutrition", 8);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10010, "Rose", "Bond","Music", 7);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10011, "Rita", "Johnson","Nutrition", 8);

1 row created. SQL> SQL> INSERT INTO lecturer (id, first_name, last_name, major,current_credits)

 2                VALUES (10012, "Sharon", "Clear","Computer Science", 3);

1 row created. SQL> SQL> SQL> DECLARE

 2    myLecturerID lecturer.ID%TYPE;
 3
 4    CURSOR c_AllStudentIDs IS
 5      SELECT ID FROM lecturer;
 6  BEGIN
 7    OPEN c_AllStudentIDs;
 8
 9    OPEN c_AllStudentIDs;
10  END;
11  /

DECLARE

ERROR at line 1: ORA-06511: PL/SQL: cursor already open ORA-06512: at line 5 ORA-06512: at line 9

SQL> SQL> SQL> drop table lecturer; Table dropped. SQL> SQL>

</source>