數據庫原理及應用.實驗6.存儲過程、觸發器的創建和使用


實驗報告

課程名稱:數據庫原理及應用

實驗項目名稱:存儲過程、觸發器的創建和使用

實驗時間:2021 年 6 月 23 日


實驗目的

  1. 了解觸發器的概念
  2. 掌握創建觸發器的方法
  3. 掌握查看、刪除觸發器信息的方法
  4. 了解存儲過程的概念
  5. 掌握創建、執行存儲過程的方法
  6. 了解查看、修改和刪除存儲過程的方法

實驗環境

MySQL、SQLyog

實驗內容及過程

在課本 P79 頁的學生-課程數據庫基礎上,完成以下實驗內容

1.觸發器

  1. 定義 BEFORE 行級觸發器,為 Stduent 表定義完整性規則“學生的年齡的取值范圍為 14~50 的整數”,若年齡的值不在 14~50 之間,則拒絕修改或插入,並拋出提示信息,以便於操作者查找問題。(需定義兩個觸發器,分別為 insert 事件和 update 事件類型),需要設計測試例子驗證觸發器是否工作。
DELIMITER //
CREATE TRIGGER trig_insert_student
BEFORE INSERT ON student
FOR EACH ROW
BEGIN
    DECLARE msg VARCHAR(200);
    IF new.sage NOT BETWEEN 14 AND 50 THEN
    SET msg = CONCAT('插入時出錯,您輸入的年齡:', new.sage, '為無效值,請輸入 14 到 50 以內的有效值。');
    SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = msg;
    END IF;
END//
DELIMITER ;
INSERT Student(Sno, Sname, Ssex, Sage, Sdept) 
VALUES    (201215129,'小明','男',13,'CS');
DROP TRIGGER IF EXISTS trig_update_student;
DELIMITER //
CREATE TRIGGER trig_update_student
BEFORE UPDATE ON student
FOR EACH ROW
BEGIN
    DECLARE msg VARCHAR(200);
    IF new.sage NOT BETWEEN 14 AND 50 THEN
    SET msg = CONCAT('更新時出錯,您輸入的年齡:', new.sage, '為無效值,請輸入 14 到 50 以內的有效值。');
    SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = msg;
    END IF;
END//
DELIMITER ;
UPDATE student
SET Sage=13
WHERE Sno=201215121;
  1. 定義一個觸發器,當一個學生的選課記錄被刪除時,把該學生學號、課程號、成績添加到 deletesc 表中,需要設計測試例子驗證觸發器是否工作。
USE st;
CREATE TABLE DELETESC
    (Sno CHAR(9),
    Cno CHAR(4),
    Grade SMALLINT
    );
DROP TRIGGER IF EXISTS trig_del_student;
DELIMITER//
CREATE TRIGGER trig_del_student
AFTER DELETE ON SC 
FOR EACH ROW
BEGIN
    INSERT INTO DELETESC
    VALUES(old.Sno,old.Cno,old.Grade);
END//
DELIMITER ;
DELETE FROM SC
WHERE Sc.Sno = '201215122';
SELECT *
FROM DELETESC;
  1. 限制數據結構課程最多 5 名學生選修,需要設計測試例子驗證觸發器是否工作。
DELIMITER //
CREATE TRIGGER trig_insert_sc
BEFORE INSERT ON SC
FOR EACH ROW
BEGIN
    DECLARE num INT;
    DECLARE msg VARCHAR(200);
    DECLARE cname VARCHAR(200);
    SET cname = '數據結構';
    SELECT COUNT(*) INTO num FROM course, sc
    WHERE course.cno = sc.cno AND course.cname = cname;
    IF num >= 5 THEN
    SET msg = CONCAT('當前',cname,'選修人數:', num,' 最大選修人數為 5' );
    SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = msg;
    END IF;

END//
DELIMITER ;
INSERT Student(Sno, Sname, Ssex, Sage, Sdept) 
VALUES    (201215124,'小明','男',20,'CS'),
    (201215126,'小紅','男',19,'IS');
INSERT INTO sc VALUES('201215121', 5, 90);
INSERT INTO sc VALUES('201215122', 5, 90);
INSERT INTO sc VALUES('201215123', 5, 90);
INSERT INTO sc VALUES('201215124', 5, 90);
INSERT INTO sc VALUES('201215125', 5, 90);
  1. 查看 (1) 觸發器的創建信息
SHOW CREATE TRIGGER trig_insert_student;
  1. 刪除 (2) 所創建的觸發器
DROP TRIGGER IF EXISTS trig_del_student;
  1. (選做題)定義一個觸發器,當插入一條新生記錄時,關系 studentcount(dept CHAR(20), stucount SMALLINT)中對應系的學生總人數需跟着改變,若關系 studentcount 中對應系已存在,只需要更新總人數,若不存在,需插入系名及總人數。需要設計測試例子驗證觸發器是否工作。
USE st;
CREATE TABLE StudentCount
    (dept CHAR(20),
    stucount SMALLINT
    );
DROP TRIGGER IF EXISTS trig_update_studentcount;
DELIMITER //
CREATE TRIGGER trig_update_studentcount
AFTER INSERT ON Student
FOR EACH ROW
BEGIN
    DECLARE exist INT;
    SET exist = EXISTS (SELECT * FROM studentcount WHERE StudentCount.dept=new.Sdept);
    IF exist = 0 THEN
        INSERT INTO StudentCount
        SELECT Sdept,COUNT(Sno)
        FROM student
        WHERE student.Sdept=new.Sdept
        GROUP BY Sdept; 
    ELSE
        UPDATE studentcount
        SET stucount=stucount+1
        WHERE StudentCount.dept=new.Sdept;
    END IF;

END//
DELIMITER ;
UPDATE studentcount
SET stucount=stucount+1
WHERE StudentCount.dept='IS';
SELECT EXISTS (SELECT * FROM studentcount WHERE StudentCount.dept='IS')
SELECT EXISTS (SELECT * FROM studentcount WHERE StudentCount.dept='de')
INSERT Student(Sno, Sname, Ssex, Sage, Sdept) 
VALUES    (201215127,'小張','男',20,'CS');

2.存儲過程

  1. 創建一個存儲過程,完成的功能是在表 student,course 和 sc 中查詢以下字段:學號、姓名、課程名稱、考試分數,需調用該存儲過程驗證結果。
USE st;
DELIMITER //
CREATE PROCEDURE get_basic_info()
BEGIN
    SELECT Student.Sno,Student.Sname,Course.Cname,Sc.Grade
    FROM Student,Course,Sc
    WHERE Student.Sno=Sc.Sno AND Sc.Cno=Course.Cno;
END //
DELIMITER ;
CALL get_basic_info();
  1. 創建一個帶有參數的存儲過程,該存儲過程根據傳入的學生編號,在 student 表中查詢此學生的信息,需調用該存儲過程驗證結果。
DELIMITER //
CREATE PROCEDURE get_stu_by_sno(IN Sno CHAR(9))
BEGIN
    SELECT *
    FROM Student
    WHERE Student.Sno=Sno;
END //
DELIMITER ;
CALL get_stu_by_sno('201215121');
  1. 創建存儲過程,根據指定的課程名(輸入參數)返回該課程的最高分、最低分、平均分(輸出參數)。要求在創建存儲過程前要先判斷該存儲過程是否已存在,如果存在,則將其刪除,需調用該存儲過程驗證結果。
DROP PROCEDURE IF EXISTS get_course_score;
DELIMITER //
CREATE PROCEDURE get_course_score(IN Cname CHAR(4),
                OUT max_grade SMALLINT,
                OUT min_grade SMALLINT,
                OUT avg_grade SMALLINT)
BEGIN
    SELECT MAX(Grade),MIN(Grade),AVG(Grade) INTO max_grade,min_grade,avg_grade
    FROM SC,course
    WHERE Course.Cname=Cname AND Course.Cno=SC.Cno;
END //
DELIMITER ;
SET @max_grade = 0,@min_grade=0,@avg_grade=0;
CALL get_course_score('數據結構',@max_grade,@min_grade,@avg_grade);
SELECT @max_grade,@min_grade,@avg_grade;
  1. 使用 SHOW CREATE 查看(1)中存儲過程信息,SHOW STATUS 查看 (2) 中存儲過程信息,從 information_schema.routine 表中查看 (3) 中存儲過程信息。
SHOW CREATE PROCEDURE get_basic_info;
SHOW PROCEDURE STATUS LIKE 'get_stu_by_sno';
USE information_schema;
SELECT *
FROM routines
WHERE routine_name = 'get_course_score';
  1. 修改 (1) 中的存儲過程定義,將讀寫權限改為 MODIFIES SQL DATA,並指明調用者可以執行,添加注釋信息。
ALTER  PROCEDURE  get_basic_info
MODIFIES SQL DATA  
SQL SECURITY INVOKER; 
  1. 刪除 (1) 中的存儲過程
DROP PROCEDURE IF EXISTS get_basic_info;
  1. (選做題)統計離散數學的成績分部情況,即按照分數段統計人數。
DROP PROCEDURE IF EXISTS get_course_score_status;
DELIMITER //
CREATE PROCEDURE get_course_score_status(IN Cno CHAR(4))
BEGIN
    SELECT MAX(Grade),MIN(Grade),AVG(Grade) INTO max_grade,min_grade,avg_grade
    FROM SC
    WHERE SC.Cno=Cno;
END //
DELIMITER ;
  1. (選做題)統計任意一門課的平均成績
DROP PROCEDURE IF EXISTS get_course_avg_score;
DELIMITER //
CREATE PROCEDURE get_course_avg_score(IN Cno CHAR(4))
BEGIN
    SELECT AVG(Grade) INTO max_grade,min_grade,avg_grade
    FROM SC
    WHERE SC.Cno=Cno;
END //
DELIMITER ;
  1. (選做題)將學生選課成績從百分制改為等級制(即 A B C D E)
ALTER TABLE SC
ADD Lev CHAR(4);
DELIMITER //
CREATE PROCEDURE SClev()
BEGIN
    UPDATE SC SET Lev='A' WHERE Grade>=90 AND Grade <=100;
    UPDATE SC SET Lev='B' WHERE Grade>=80 AND Grade<90;
    UPDATE SC SET Lev='C' WHERE Grade>=70 AND Grade<80;
    UPDATE SC SET Lev='D' WHERE Grade>=60 AND Grade<70;
    UPDATE SC SET Lev='E' WHERE Grade<60;
END //
DELIMITER ;

EXEC SClev;
SELECT * FROM SC;

實驗心得

  通過本次實驗,我了解觸發器的概念,掌握創建觸發器的方法,掌握查看、刪除觸發器信息的方法,了解存儲過程的概念,掌握創建、執行存儲過程的方法,同時了解查看、修改和刪除存儲過程的方法,收獲頗豐。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM