📄 05-mutat.sql
字号:
REM 05-MUTAT.SQL
REM This file contains the mutating table examples
REM used in Chapter 5 of "Oracle PL/SQL Programming".
REM This is version 1.0 of this file, updated 2/18/96.
REM Comments and questions should go to Scott Urman at
REM surman@us.oracle.com.
REM *** Chapter 5: Legal Trigger ***
CREATE OR REPLACE TRIGGER CascadeRSInserts
/* Keep the registered_students, students, and classes
tables in synch. */
BEFORE INSERT ON registered_students
FOR EACH ROW
DECLARE
v_Credits classes.num_credits%TYPE;
BEGIN
-- Determine the number of credits for this class.
SELECT num_credits
INTO v_Credits
FROM classes
WHERE department = :new.department
AND course = :new.course;
-- Modify the current credits for this student.
UPDATE students
SET current_credits = current_credits + v_Credits
WHERE ID = :new.student_id;
-- Add one to the number of students in the class.
UPDATE classes
SET current_students = current_students + 1
WHERE department = :new.department
AND course = :new.course;
END CascadeRSInserts;
/
REM *** Chapter 5: Trigger Which Modifies a Mutating Table ***
CREATE OR REPLACE TRIGGER LimitMajors
/* Limits the number of students in each major to 5.
If this limit is exceeded, an error is raised through
raise_application_error. */
BEFORE INSERT OR UPDATE OF major ON students
FOR EACH ROW
DECLARE
v_MaxStudents CONSTANT NUMBER := 5;
v_CurrentStudents NUMBER;
BEGIN
-- Determine the current number of students in this
-- major.
SELECT COUNT(*)
INTO v_CurrentStudents
FROM students
WHERE major = :new.major;
-- If there isn't room, raise an error.
IF v_CurrentStudents + 1 > v_MaxStudents THEN
RAISE_APPLICATION_ERROR(-20000,
'Too many students in major ' || :new.major);
END IF;
END LimitMajors;
/
REM *** Chapter 5: Solution for the Mutating Tables Problem ***
CREATE OR REPLACE PACKAGE StudentData AS
TYPE t_Majors IS TABLE OF students.major%TYPE
INDEX BY BINARY_INTEGER;
TYPE t_IDs IS TABLE OF students.ID%TYPE
INDEX BY BINARY_INTEGER;
v_StudentMajors t_Majors;
v_StudentIDs t_IDs;
v_NumEntries BINARY_INTEGER := 0;
END StudentData;
/
CREATE OR REPLACE TRIGGER RLimitMajors
BEFORE INSERT OR UPDATE OF major ON students
FOR EACH ROW
BEGIN
/* Record the new data in StudentData. We don't make any
changes to students, to avoid the ORA-4091 error. */
StudentData.v_NumEntries := StudentData.v_NumEntries + 1;
StudentData.v_StudentMajors(StudentData.v_NumEntries) :=
:new.major;
StudentData.v_StudentIDs(StudentData.v_NumEntries) := :new.id;
END RLimitMajors;
/
CREATE OR REPLACE TRIGGER SLimitMajors
AFTER INSERT OR UPDATE OF major ON students
DECLARE
v_MaxStudents CONSTANT NUMBER := 5;
v_CurrentStudents NUMBER;
v_StudentID students.ID%TYPE;
v_Major students.major%TYPE;
BEGIN
/* Loop through each student inserted or updated, and verify
that we are still within the limit. */
FOR v_LoopIndex IN 1..StudentData.v_NumEntries LOOP
v_StudentID := StudentData.v_StudentIDs(v_LoopIndex);
v_Major := StudentData.v_StudentMajors(v_LoopIndex);
-- Determine the current number of students in this major.
SELECT COUNT(*)
INTO v_CurrentStudents
FROM students
WHERE major = v_Major;
-- If there isn't room, raise an error.
IF v_CurrentStudents > v_MaxStudents THEN
RAISE_APPLICATION_ERROR(-20000,
'Too many students for major ' || v_Major ||
' because of student ' || v_StudentID);
END IF;
END LOOP;
-- Reset the counter so the next execution will use new data.
StudentData.v_NumEntries := 0;
END SLimitMajors;
/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -