您的位置:首页 > 数据库

PLSQL==>>游标

2014-11-20 20:27 295 查看
1.记录类型:基于表的(table_based),基于游标(cursor_based),以及程序员定义的(programmer-defined),为创建一个基于表或者基于游标的记录,可以使用%ROWTYPE属性:

DECLARE

    vr_student student%ROWTYPE;

BEGIN

    SELECT * INTO vr_student FROM student WHERE student_id = 156;

    dbms_output.put_line(vr_student.first_name || ' ' ||

                         vr_student.last_name || ' has and ID of 156');

EXCEPTION

    WHEN no_data_found THEN

        raise_application_error(-2001,

                                'The Student ' || 'is not in the database');

END;

2.处理显示游标:

DECLARE

    CURSOR c_student_name IS

        SELECT first_name, last_name FROM student WHERE rownum <= 5;

    vr_student_name c_student_name%ROWTYPE;

BEGIN

    OPEN c_student_name;

    LOOP

        FETCH c_student_name

            INTO vr_student_name;

        EXIT WHEN c_student_name%NOTFOUND;

        dbms_output.put_line('Student name: ' ||

                             vr_student_name.first_name || ' ' ||

                             vr_student_name.last_name);

    END LOOP;

    CLOSE c_student_name;

END;

3.处理用户定义的记录:

DECLARE

    TYPE instructor_info IS RECORD(

        first_name instructor.first_name%TYPE,

        last_name  instructor.last_name%TYPE,

        sections   NUMBER);

    rv_instructor instructor_info;

BEGIN

    SELECT rtrim(i.first_name), rtrim(i.last_name), COUNT(*)

      INTO rv_instructor

      FROM instructor i, section s

     WHERE i.instructor_id = s.instructor_id

       AND i.instructor_id = 102

     GROUP BY i.first_name, i.last_name;

    dbms_output.put_line('Instructor, ' || rv_instructor.first_name || ' ' ||

                         rv_instructor.last_name || ',teachees ' ||

                         rv_instructor.sections || ' section(s)');

EXCEPTION

    WHEN OTHERS THEN

        dbms_output.put_line('There is no instructor');

END;

游标属性rowcount:

DECLARE

    v_city zipcode.city%TYPE;

BEGIN

    SELECT city INTO v_city FROM zipcode WHERE zip = 07002;

    IF SQL%ROWCOUNT = 1

    THEN

        dbms_output.put_line(v_city || 'has a ' || 'zipcode of 07002');

    ELSIF SQL%ROWCOUNT = 0

    THEN

        dbms_output.put_line('The zipcode 07002 is ' ||

                             ' not in the database');

    ELSE

        dbms_output.put_line('Stop harassing me');

    END IF;

END;

集成所有游标属性:

DECLARE

    v_sid student.student_id%TYPE;

    CURSOR c_student IS

        SELECT student_id FROM student WHERE student_id < 200;

BEGIN

    OPEN c_student;

    LOOP

        FETCH c_student

            INTO v_sid;

        EXIT WHEN c_student%NOTFOUND;

        dbms_output.put_line('STUDNET ID: ' || v_sid);

    END LOOP;

    CLOSE c_student;

EXCEPTION

    WHEN OTHERS THEN

        IF c_student%ISOPEN

        THEN

            CLOSE c_student;

        END IF;

END;

修改版本:

DECLARE

    v_sid student.student_id%TYPE;

    CURSOR c_student IS

        SELECT student_id FROM student WHERE student_id < 110;

BEGIN

    OPEN c_student;

    LOOP

        FETCH c_student

            INTO v_sid;

        IF c_student%FOUND

        THEN

            dbms_output.put_line('Just FETCHED row ' ||

                                 to_char(c_student%ROWCOUNT) ||

                                 ' Student ID: ' || v_sid);

        ELSE

            EXIT;

        END IF;

    END LOOP;

    CLOSE c_student;

EXCEPTION

    WHEN OTHERS THEN

        IF c_student%ISOPEN

        THEN

            CLOSE c_student;

        END IF;

END;

DECLARE

    CURSOR c_student_enroll IS

        SELECT s.student_id,

               s.first_name,

               s.last_name,

               COUNT(*) enroll,

               (CASE

                   WHEN COUNT(*) = 1 THEN

                    'class.'

                   WHEN COUNT(*) IS NULL THEN

                    'no classes.'

                   ELSE

                    'classes.'

               END) CLASS

          FROM student s, enrollment e

         WHERE s.student_id = e.student_id

           AND s.student_id < 110

         GROUP BY s.student_id, first_name, last_name;

    r_student_enroll c_student_enroll%ROWTYPE;

BEGIN

    OPEN c_student_enroll;

    LOOP

        FETCH c_student_enroll

            INTO r_student_enroll;

        EXIT WHEN c_student_enroll%NOTFOUND;

        dbms_output.put_line('Student INFO: ID ' ||

                             r_student_enroll.student_id || ' is ' ||

                             r_student_enroll.first_name || ' ' ||

                             r_student_enroll.last_name ||

                             ' is enrolled in ' || r_student_enroll.enroll || ' ' ||

                             r_student_enroll.class);

    END LOOP;

    CLOSE c_student_enroll;

EXCEPTION

    WHEN OTHERS THEN

        IF c_student_enroll%ISOPEN

        THEN

            CLOSE c_student_enroll;

        END IF;

END;

使用游标FOR循环:

DECLARE

    CURSOR c_student IS

        SELECT student_id, last_name, first_name

          FROM student

         WHERE student_id < 110;

BEGIN

    FOR r_student IN c_student

    LOOP

        INSERT INTO table_log VALUES (r_student.last_name);

    END LOOP;

END;

DECLARE

    CURSOR c_group_discount IS

        SELECT DISTINCT s.course_no

          FROM section s, enrollment e

         WHERE s.section_id = e.section_id

         GROUP BY s.course_no, e.section_id, s.section_id

        HAVING COUNT(*) >= 8;

BEGIN

    FOR r_group_discount IN c_group_discount

    LOOP

        UPDATE course

           SET cost = cost * 0.95

         WHERE course_no = r_group_discount.course_no;

    END LOOP;

END;;

2.处理嵌套的游标(1):

DECLARE

    v_zip          zipcode.zip%TYPE;

    v_student_flag CHAR;

    CURSOR c_zip IS

        SELECT zip, city, state FROM zipcode WHERE state = 'CT';

    CURSOR c_student IS

        SELECT first_name, last_name FROM student WHERE zip = v_zip;

BEGIN

    FOR r_zip IN c_zip

    LOOP

        v_student_flag := 'N';

        v_zip          := r_zip.zip;

        dbms_output.put_line(chr(10));

        dbms_output.put_line('Student living in ' || r_zip.city);

        FOR r_student IN c_student

        LOOP

            dbms_output.put_line(r_student.first_name || ' ' ||

                                 r_student.last_name);

            v_student_flag := 'Y';

        END LOOP;

        IF v_student_flag = 'N'

        THEN

            dbms_output.put_line('NO Students for this zipcode');

        END IF;

    END LOOP;

END;

3.处理嵌套的游标(2):

DECLARE

    v_amount        course.cost%TYPE;

    v_instructor_id instructor.instructor_id%TYPE;

    CURSOR c_inst IS

        SELECT first_
4000
name, last_name, instructor_id FROM instructor;

    CURSOR c_cost IS

        SELECT c.cost

          FROM course c, section s, enrollment e

         WHERE s.instructor_id = v_instructor_id

           AND c.course_no = s.course_no

           AND s.section_id = e.section_id;

BEGIN

    FOR r_inst IN c_inst

    LOOP

        v_instructor_id := r_inst.instructor_id;

        v_amount        := 0;

        dbms_output.put_line('Amount generated by instructor ' ||

                             r_inst.first_name || ' ' || r_inst.last_name || ' is ');

        FOR r_cost IN c_cost

        LOOP

            v_amount := v_amount + nvl(r_cost.cost, 0);

        END LOOP;

        dbms_output.put_line(' ' || to_char(v_amount, '$999,999'));

    END LOOP;

END;

练习:(1)

DECLARE

    CURSOR c_course IS

        SELECT course_no, description FROM course WHERE course_no < 120;

    CURSOR c_enrollment(p_course_no IN course.course_no%TYPE) IS

        SELECT s.section_no section_no, COUNT(*) COUNT

          FROM section s, enrollment e

         WHERE s.course_no = p_course_no

           AND s.section_id = e.student_id

         GROUP BY s.section_no;

BEGIN

    FOR r_course IN c_course

    LOOP

        dbms_output.put_line(r_course.course_no || ' ' ||

                             r_course.description);

        FOR r_enroll IN c_enrollment(r_course.course_no)

        LOOP

            dbms_output.put_line(chr(9) || 'Section: ' ||

                                 r_enroll.section_no ||

                                 ' has an enrollment of: ' ||

                                 r_enroll.count);

        END LOOP;

    END LOOP;

END;

练习:(2)

DECLARE

    CURSOR c_student_enroll IS

        SELECT s.student_id,

               s.first_name,

               s.last_name,

               COUNT(*) enroll,

               /*(CASE

                   WHEN COUNT(*) = 1 THEN

                    'class'

                   WHEN COUNT(*) IS NULL THEN

                    'no clasr'

                   ELSE

                    'classes'

               END) CLASS*/

               decode(COUNT(*), 1, 'CLASS', NULL, 'no classes.', 'classes') CLASS

          FROM student s, enrollment e

         WHERE s.student_id = e.student_id

           AND s.student_id < 110

         GROUP BY s.student_id, first_name, last_name;

    r_student_enroll c_student_enroll%ROWTYPE;

BEGIN

    OPEN c_student_enroll;

    LOOP

        FETCH c_student_enroll

            INTO r_student_enroll;

        EXIT WHEN c_student_enroll%NOTFOUND;

        dbms_output.put_line('Student INFO: ID ' ||

                             r_student_enroll.student_id || ' is ' ||

                             r_student_enroll.first_name || ' ' ||

                             r_student_enroll.last_name ||

                             ' is enrolled in  ' ||

                             r_student_enroll.enroll || ' ' ||

                             r_student_enroll.class);

    END LOOP;

    CLOSE c_student_enroll;

EXCEPTION

    WHEN OTHERS THEN

        IF c_student_enroll%ISOPEN

        THEN

            CLOSE c_student_enroll;

        END IF;

END;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: