MySQL实验(三) 过程式数据库对象的使用

一、目的与要求

(1)掌握存储过程创建和调用的方法;
(2)掌握MySQL中程序片段的组成;
(3)掌握游标的使用方法;
(4)掌握存储函数创建和调用的方法;
(5)掌握触发器的使用方法;
(6)掌握事件的创建和使用方法;

二、实验内容

(1)了解存储过程体中允许的SQL语句类型和参数的定义方法;
(2)了解存储过程的调用方法;
(3)了解存储函数的定义和调用方法;
(4)了解触发器的作用和调用方法;
(5)了解事件的作用和定义方法;

三、实验结果

1.存储过程
(1)创建存储过程,使用Employees表中的员工人数来初始化一个局部变量,并调用这个存储过程。

USE YGGL
DELIMITER $$
CREATE PROCEDURE TEST(OUT NUMBER1 INTEGER)
BEGIN
	DECLARE NUMBER2 INTEGER;
	SET NUMBER2=(SELECT COUNT(*) FROM Employees);
	SET NUMBER1=NUMBER2;
END $$
DELIMITER;

MySQL实验(三) 过程式数据库对象的使用_第1张图片

CALL TEST(@NUMBER);
select @NUMBER;

MySQL实验(三) 过程式数据库对象的使用_第2张图片
(2)创建存储过程,比较两个员工的实际收入,若前者比后者高就输出0,否则输出1.

DELIMITER $$
CREATE PROCEDURE
	COMPA(IN ID1 CHAR(6),IN ID2 CHAR(6),OUT BJ INTEGER)
BEGIN 
	DECLARE SR1,SR2 FLOAT(8);
	SELECT InCome-OuTCome INTO SR1 FROM Salary WHERE EmployeesID=ID1;
	SELECT InCome-OuTCome INTO SR2 FROM Salary WHERE EmployeesID=ID2;
	IF ID1>ID2 THEN
		SET BJ=0;
	ELSE 
		SET BJ=1;
	END IF;
END$$
DELIMITER;

MySQL实验(三) 过程式数据库对象的使用_第3张图片

CALL COMPA('000001','108991',@BJ);
SELECT @BJ;

MySQL实验(三) 过程式数据库对象的使用_第4张图片
(3)创建存储过程,使用游标确定一个员工的实际收入是否排在前三名。结果为TRUE表示是,结果为FLASE表示否;

DELIMITER $$
CREATE PROCEDURE
TOP_THREE (IN EM_ID CHAR(6),OUT OK BOOLEAN)
BEGIN 
	DECLARE X_EM_ID CHAR(6);
	DECLARE ACT_IN,SEQ INTEGER;
	DECLARE FOUND BOOLEAN;
	DECLARE SALARY_DIS CURSOR FOR
	SELECT EmployeesID,InCome-OutCome
	FROM Salary 
	ORDER BY 2 DESC;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET FOUND=FALSE;
SET SEQ=0;
SET FOUND=TRUE;
SET OK=FALSE;
OPEN SALARY_DIS;
FETCH SALARY_DIS INTO X_EM_ID,ACT_IN;
WHILE FOUND AND SWQ<3 AND OK=FALSE DO
	SET SEQ=SEQ+1;
	IF X_EM_ID=EM_ID THEN
		SET OK=TRUE;
	END IF;
	FETCH SALARY_DIS INTO X_EM_ID,ACT_IN;
END WHILE;
CLOSE SALARY_DIS;
END $$
DELIMITER;

MySQL实验(三) 过程式数据库对象的使用_第5张图片
2.存储函数
创建一个存储函数,返回员工的总人数。

CREATE FUNCTION EM_MUM()
    RETURNS INTEGER
    RETURN(SELECT COUNT(*) FROM Employees);

select EM_MUM();

MySQL实验(三) 过程式数据库对象的使用_第6张图片
(2)创建一个存储函数,删除在Salary表中但在Employees表中不存在的员工号。若在Employees表中存在返回FALSE,若不存在则删除该工号并返回TRUE.

DELIMITER $$
CREATE FUNCTION DELETE_EM(EM_ID CHAR(6))
	RETURNS BOOLEAN
BEGIN 
	DECLARE EM_NAME CHAR(10);
	SELECT Name INTO EM_NAME FROM Employees WHERE EmployeesID=EM_ID;
	IF EM_NAME IS NULL THEN
		DELETE FROM Salary WHERE EmployeesID=EM_ID;
		RETURN TRUE;
	ELSE
		RETURN FALSE;
	END IF;
END$$
DELIMITER ;

MySQL实验(三) 过程式数据库对象的使用_第7张图片
SELECT DELETE_EM(‘000001’);
MySQL实验(三) 过程式数据库对象的使用_第8张图片
3.触发器
(1)创建触发器,在Employees表中删除员工信息的同时将Salary表中该员工的2信息删除,以确保数据完整性;

CREATE TRIGGER DELETE_EM AFTER DELETE
    ON Employees FOR EACH ROW
    DELETE FROM Salary 
            WHERE EmployeesID=OLD.EmployeesID;

MySQL实验(三) 过程式数据库对象的使用_第9张图片

delete from Employees where EmployeesID="010008";

这里写图片描述
select * from Employees;
MySQL实验(三) 过程式数据库对象的使用_第10张图片
select * from Salary;
MySQL实验(三) 过程式数据库对象的使用_第11张图片
(2)假设Deaprtments2表和Departments表的结构和内容都相同,在Departments上创建一个触发器,如果添加一新的部门,该部门也会添加到Departments2表中;
创建一个与Departments表结构相同的Departments2表;

create table Departments2 like Departments;

这里写图片描述

MySQL实验(三) 过程式数据库对象的使用_第12张图片

这里写图片描述

DELIMITER $$
CREATE TRIGGER Departments_Ins
	AFTER INSERT ON Departments FOR EACH ROW
BEGIN
	INSERT INTO Departments2 VALUES(NEW. DepartmentID,NEW. DepartmentName,NEW.Note);
END$$
DELIMITER ;

MySQL实验(三) 过程式数据库对象的使用_第13张图片

insert into Departments values(‘6’,’网络部’,”);
这里写图片描述
MySQL实验(三) 过程式数据库对象的使用_第14张图片
select * from Departments2;
MySQL实验(三) 过程式数据库对象的使用_第15张图片
(3)当修改表Employee2时,若将Employees表中员工的工作时间增加一年,则将收入增加500,增加2年则增加1000,。依次增加。若工作时间减少则无变化;

DELIMITER $$
CREATE TRIGGER ADD_SALARY
	AFTER UPDATE ON Employees FOR EACH ROW
BEGIN
	DECLARE YEARS INTEGER;
	SET YEARS=NEW.WorkYear-OLD.WorkYear;
	IF YEARS>0 THEN
		UPDATE Salary SET InCome=InCome+500*YEARS
			WHERE Employees=NEW.EmployeesID;
	END IF;
END$$
DELIMITER ;

MySQL实验(三) 过程式数据库对象的使用_第16张图片
SELECT * from Salary;
MySQL实验(三) 过程式数据库对象的使用_第17张图片

update Employees
set WorkYear=WorkYear+2;

replace into Employees values('000001','王林','大专','1966-01-23','1',10,'中山路32-1-508','83355668','2');

这里写图片描述
select * from Employees;
MySQL实验(三) 过程式数据库对象的使用_第18张图片
SELECT * from Salary;
MySQL实验(三) 过程式数据库对象的使用_第19张图片
4.事件
创建一个立即执行的事件,查询Employees表的信息;

CREATE EVENT direct_happen
    ON SCHEDULE AT NOW()
    DO
        SELECT * FROM Employees;

这里写图片描述
(2)创建一个时间,每天执行一次,它从2015年12月31日结束;

DELIMITER $$
CREATE EVENT every_day
	on SCHEDULE EVERY 1 DAY
		STARTS CURDATE()+INTERVAL 1 DAY
		ENDS '2015-12-31'
	DO
	BEGIN	
		SELECT * FROM Employees;
	END$$
DELIMITER ;

MySQL实验(三) 过程式数据库对象的使用_第20张图片

四、实验总结

本次实验主要的内容为创建、调用、删除、修改过程体、存储函数、触发器、事件。感觉做起来难度有点大,主要还是因为不熟悉这些基本原理。期间有些问题解决了,还有一些仍待解决;本次试验中感觉到了数据库中的过程式存储对象对于数据库实现复杂·的功能是必不可少的一环,过程式数据库对象确实功能非常强大。

五、代码

#####实验六################
select 194*142;

select 'I\nlove\nMySQL';

select @@VERSION;

select CURRENT_TIME;

use YGGL
set @female=0;

select EmployeesID,Name
    from Employees
    where sex=@female;

set @phone=(select PhoneNumber
    from Employees
    where EmployeesID='111006');
select @phone;

select InCome-OutCome
    from Salary;

select *
    from Employees
    where WorkYear > 5;

select (7>6) AND ('A'='B');

select GREATEST(5,76,25.9),LEAST(5,76,25.9);

SELECT ROUND(5.33);
SELECT ABS(-5);
SELECT SQRT(9);

SELECT COUNT(EmployeesID) as 广告部人数
    from Employees
    where DepartmentID=
    (SELECT DepartmentID
        from Departments
        where DepartmentName='广告部');

select CONCAT('Ilove','MySQL');

select ASCII('ABC');

select NOW();

SELECT YEAR(Birthday)
    from Employees
    where EmployeesID='000001';
############### 实验七####################
USE YGGL
DELIMITER $$
CREATE PROCEDURE TEST(OUT NUMBER1 INTEGER)
BEGIN
	DECLARE NUMBER2 INTEGER;
	SET NUMBER2=(SELECT COUNT(*) FROM Employees);
	SET NUMBER1=NUMBER2;
END $$
DELIMITER;

CALL TEST(@NUMBER);
select @NUMBER;

DELIMITER $$
CREATE PROCEDURE
	COMPA(IN ID1 CHAR(6),IN ID2 CHAR(6),OUT BJ INTEGER)
BEGIN 
	DECLARE SR1,SR2 FLOAT(8);
	SELECT InCome-OuTCome INTO SR1 FROM Salary WHERE EmployeesID=ID1;
	SELECT InCome-OuTCome INTO SR2 FROM Salary WHERE EmployeesID=ID2;
	IF ID1>ID2 THEN
		SET BJ=0;
	ELSE 
		SET BJ=1;
	END IF;
END$$
DELIMITER;

CALL COMPA('000001','108991',@BJ);

SELECT @BJ;

CREATE FUNCTION EM_MUM()
    RETURNS INTEGER
    RETURN(SELECT COUNT(*) FROM Employees);

select EM_MUM();

DELIMITER $$
CREATE FUNCTION DELETE_EM(EM_ID CHAR(6))
	RETURNS BOOLEAN
BEGIN 
	DECLARE EM_NAME CHAR(10);
	SELECT Name INTO EM_NAME FROM Employees WHERE EmployeesID=EM_ID;
	IF EM_NAME IS NULL THEN
		DELETE FROM Salary WHERE EmployeesID=EM_ID;
		RETURN TRUE;
	ELSE
		RETURN FALSE;
	END IF;
END$$
DELIMITER ;

SELECT DELETE_EM('000001');

DELIMITER $$
CREATE PROCEDURE
TOP_THREE (IN EM_ID CHAR(6),OUT OK BOOLEAN)
BEGIN 
	DECLARE X_EM_ID CHAR(6);
	DECLARE ACT_IN,SEQ INTEGER;
	DECLARE FOUND BOOLEAN;
	DECLARE SALARY_DIS CURSOR FOR
	SELECT EmployeesID,InCome-OutCome
	FROM Salary 
	ORDER BY 2 DESC;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET FOUND=FALSE;
SET SEQ=0;
SET FOUND=TRUE;
SET OK=FALSE;
OPEN SALARY_DIS;
FETCH SALARY_DIS INTO X_EM_ID,ACT_IN;
WHILE FOUND AND SWQ<3 AND OK=FALSE DO
	SET SEQ=SEQ+1;
	IF X_EM_ID=EM_ID THEN
		SET OK=TRUE;
	END IF;
	FETCH SALARY_DIS INTO X_EM_ID,ACT_IN;
END WHILE;
CLOSE SALARY_DIS;
END $$
DELIMITER;

CREATE TRIGGER DELETE_EM AFTER DELETE
    ON Employees FOR EACH ROW
    DELETE FROM Salary 
            WHERE EmployeesID=OLD.EmployeesID;

delete from Employees where EmployeesID="010008";
select * from Employees;
select * from Salary;

create table Departments2 like Departments;

DELIMITER $$
CREATE TRIGGER Departments_Ins
	AFTER INSERT ON Departments FOR EACH ROW
BEGIN
	INSERT INTO Departments2 VALUES(NEW. DepartmentID,NEW. DepartmentName,NEW.Note);
END$$
DELIMITER ;

insert into Departments values('6','网络部','');
select * from Departments;
select * from Departments2;

DELIMITER $$
CREATE TRIGGER ADD_SALARY
	AFTER UPDATE ON Employees FOR EACH ROW
BEGIN
	DECLARE YEARS INTEGER;
	SET YEARS=NEW.WorkYear-OLD.WorkYear;
	IF YEARS>0 THEN
		UPDATE Salary SET InCome=InCome+500*YEARS
			WHERE Employees=NEW.EmployeesID;
	END IF;
END$$
DELIMITER ;

SELECT * from Salary;
update Employees
    set WorkYear=WorkYear+2;
replace into Employees values('000001','王林','大专','1966-01-23','1',10,'中山路32-1-508','83355668','2');
select * from Employees;
SELECT * from Salary;

CREATE EVENT direct_happen
    ON SCHEDULE AT NOW()
    DO
        SELECT * FROM Employees;

DELIMITER $$
CREATE EVENT every_day
	on SCHEDULE EVERY 1 DAY
		STARTS CURDATE()+INTERVAL 1 DAY
		ENDS '2015-12-31'
	DO
	BEGIN	
		SELECT * FROM Employees;
	END$$
DELIMITER ;

你可能感兴趣的:(数据库)