数据库实验系列之3存储过程和触发器实验(存储过程和触发器)

实验9:存储过程实验

自拟题目完成8个存储过程的编写及调试,熟练掌握存储过程的使用。也可采用下图中作业上的题目。

SQL语句代码

--1.例1
use 学生作业管理数据库;
select * from 学生表;
select * from 课程表;
select * from 学生作业表;
--先查看是否存在名字为student_course的存储过程,如果有,删除
if exists (select name from  sysobjects where  name='student_course' and type='P')
drop procedure stuent_course;
--创建存储过程
create procedure student_course
as
	select 学生表.学号,姓名,课程名,作业1成绩
	from 学生表,课程表,学生作业表
	where 学生表.学号=学生作业表.学号 and 课程表.课程号=学生作业表.课程号 and 姓名='张艳'

--执行存储过程
execute student_course;

--带输入参数的存储过程
create procedure  student_course1
@Studentname varchar(10)
as
	select 学生表.学号,姓名,课程名,作业1成绩
	from 学生表,课程表,学生作业表
	where 学生表.学号=学生作业表.学号 and 课程表.课程号=学生作业表.课程号 and 姓名=@Studentname;

--调用student_course1
execute student_course1 '于兰兰';

--创建一个存储过程用于向学生表中插入记录
create procedure student_insert
@学号 int,@姓名 nvarchar(10),@性别 nvarchar(2),@专业班级 nvarchar(10),@出生日期 nvarchar(20),@联系电话 nvarchar(20)
as
	INSERT into 学生表
	values(@学号,@姓名,@性别,@专业班级,@出生日期,@联系电话);

--执行student_insert
execute student_insert '007','阿刚','男','电子06','2000-1-1','13333333333';


--创建存储过程,若没有给出学生姓名,则返回所有学生情况
create procedure student_course2
@StudentName nvarchar(20)=null
as
	if @StudentName is null
	begin 
		select 学生表.学号,姓名,课程名,作业1成绩
		from 学生表,课程表,学生作业表
		where 学生表.学号=学生作业表.学号 and 课程表.课程号=学生作业表.课程号
	end
	else
	begin
		select 学生表.学号,姓名,课程名,作业1成绩
		from 学生表,课程表,学生作业表
		where 学生表.学号=学生作业表.学号 and 课程表.课程号=学生作业表.课程号 and 姓名=@Studentname;
	end

execute student_course2 '张志国';
execute student_course2;			--使用默认参数值


--使用输出参数
CREATE procedure student_count
@CourseName varchar(20),
@StudentSum int output
as
	select @StudentSum=COUNT(*)
	from 课程表,学生作业表
	where 课程表.课程号=学生作业表.课程号 and 课程名=@CourseName;


--对于带有输出参数的存储过程,调用时需要定义相应的变量用于接收从存储过程返回的参数值
declare @StudentSum1 int;
execute student_count '数据结构',@StudentSum1 OUTPUT;
SELECT @StudentSum1 as 选数据结构的人数;

--创建一个存储过程,输出学生的基本情况
alter procedure student_query
@学号 int,@姓名 nvarchar(8) output,@性别 char(2) output
as
	select @姓名=姓名,@性别=性别
	from 学生表
	where 学号=@学号;

--调用存储过程,查看基本情况
declare @姓名1 nvarchar(20);
declare @性别1 char(2);
execute student_query '7',@姓名1 output,@性别1 output;
select @姓名1 as 学生姓名,@性别1 as 学生性别;
select * from 学生表;

--删除存储过程是
--drop procedure 存储过程名;

--market数据库中
use market;
--存储过程shanghai,查看上海客户信息
select * from Customers;
insert into Customers VALUES(3,'阿美','上海');
create procedure shanghai 
as
	select * from Customers
	where City='上海'

execute shanghai;
--存储过程Goods,查看指定商品信息,商品编号作为输入参数
select * from Goods;
insert into Goods values(1,'牙膏',2.5,'牙膏厂',400,'在售');
insert into Goods values(2,'牙刷',5,'牙刷厂',1200,'热卖');
create procedure cunchuGoods
@商品编号 int
as
	select * from Goods
	where GoodID=@商品编号;

execute cunchuGoods @商品编号=2;
--存储过程GoodsSum,查看指定客户的所有订单的订货总金额,客户编号作为输入参数,订货总金额作为输出参数
select * from Orders;
insert into Orders values(1,1,1,2,5,'2020-1-1');
insert into Orders values(2,1,2,2,10,'2020-1-1');
insert into Orders values(3,2,2,2,10,'2020-1-1');
create procedure cunchuGoodsSum
@客户编号 int,@订货总金额 float output
as 
	select @订货总金额=OrderSum from Orders
	where Orders.CustomerID=@客户编号;

declare @订货总金额 float;             --切记勿忘声明变量
execute cunchuGoodsSum   2,@订货总金额 output;
select @订货总金额 as '订货总金额';

--存储过程insert_Goods,向Goods表中插入一条记录
select * from Goods;
alter procedure insert_Goods
@商品编号 int,@商品名称 nvarchar(20),@价格 float,@供货商 nvarchar(20),@库存量 int,@商品状态 nvarchar(20)
as 
	insert into Goods(GoodID,Gname,Price,Provider,Stocks,Status) 
	values(@商品编号,@商品名称,@价格,@供货商,@库存量,@商品状态);

execute insert_Goods  3,'牙刷杯',10,'牙刷杯厂',5,'即将断货';
--创建存储过程Goods_Orders1,查看任何指定货品的订单情况,包括订单号,订货客户姓名以及订货数量(使用输入参数)
select * from Orders;
select * from Goods;
select * from Customers;
CREATE procedure Goods_Orders1
@指定货品 nvarchar(20)
as
	select OrderID,Cname,Quantity from Orders,Goods,Customers
	where Orders.GoodID=Goods.GoodID and Orders.CustomerID=Customers.CustomerID AND  Goods.Gname=@指定货品;

EXECUTE Goods_Orders1 @指定货品='牙膏';


--执行存储过程,如果不给出参数则报错,如果希望不输入参数,即默认值,得到所有货品订单,则新建表Goods_Orders2
execute Goods_Orders1 @指定货品;  --报错
create procedure Goods_Orders2
@指定货品 nvarchar(20)=null
as
	if @指定货品 is null
	begin 
		select OrderID,Cname,Quantity from Orders,Goods,Customers
		where Orders.GoodID=Goods.GoodID and Orders.CustomerID=Customers.CustomerID
	end
	else
	begin
	select OrderID,Cname,Quantity from Orders,Goods,Customers
	where Orders.GoodID=Goods.GoodID and Orders.CustomerID=Customers.CustomerID AND  Goods.Gname=@指定货品
	end
execute Goods_Orders2;
execute Goods_Orders2 @指定货品='牙刷';

--创建存储过程Goods_OrderSum,来获得某个货品的订单总额(使用输入输出参数)
alter PROCEDURE Goods_OrderSum
@货品名称 nvarchar(20),@订单总额1 float output
as
	select @订单总额1=sum(OrderSum) from Orders,Goods
	where Goods.GoodID=Orders.GoodID and Gname=@货品名称;

declare @订单总额1 float;
execute Goods_OrderSum  '牙膏',@订单总额1 output;
select @订单总额1 as '订单总额';

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

实验10:触发器实验

自拟题目完成5个触发器的编写及调试,熟练掌握触发器的使用。也可采用下图中作业上的题目。

SQL语句代码

use 学生作业管理数据库;
--例8 创建一个触发器,当  学生表  中的记录被更新时,显示表中的所有记录
create trigger  student_change
	on 学生表 after insert,update,delete
	as
		select * from 学生表;

--查看下变化
select * from 学生表;
insert into 学生表 values(1,'阿美','女','计科06','2002-1-1','13312313213');

--例9 在  学生表  中创建DELETE触发器,实现对  学生表  和 学生作业表 的级联删除
create trigger studentdelete on 学生表
	after delete
as
	delete from 学生作业表
	where 学号 in
		(select deleted.学号 from deleted);
--查看下变化
select * from 学生作业表;
insert into  学生作业表 values('K001',1,99,99,99);
select * from 学生作业表;
delete  from 学生表 where 姓名='阿美';
select * from 学生作业表;

--例10 在学生作业表上创建insert 触发器,当向学生作业表 中添加学生的选课记录时,
--检查该学生的学号是否存在,若不存在,则不能将记录插入
create trigger sc_insert on 学生作业表
	after insert
as
	if(select count(*) from 学生表,inserted where 学生表.学号=inserted.学号)=0
	begin 
		print '学号不存在,不能插入'
		rollback transaction
	end;

--查看效果
insert into 学生作业表 values('K001',1,99,99,99);

--例11 创建update触发器,禁止对学生表 中学生的性别进行修改
create trigger student_update on 学生表
	after update
as 
	if update(性别)
	begin
		print '禁止对学生学号修改'
		rollback transaction
	end;
--查看效果
select * from 学生表;
update 学生表 set 性别='男' where 性别='女' and 学号=7;
select * from 学生表;

--例12 在学生作业表上创建触发器,当一次向学生作业表中添加多个记录时,删除学号在学生表中不存在的记录,
--从而保证数据的一致性,注意,不能在学生作业表中定义外键约束
create trigger sc_insert1 on 学生作业表 
	after insert
as 
	if(select count(*) from 学生表,inserted where inserted.学号=学生表.学号)<>@@ROWCOUNT
	BEGIN
		delete from 学生作业表
		where 学号 not in (select 学号 from 学生表)
	END;


--例13 在视图上定义instead of 触发器
select * from 学生表;
create view birth_view(学号,姓名,性别,生日,专业班级)
as 
	select 学号,姓名,性别,出生日期,专业班级
	from 学生表;

create trigger birth_view_insert on birth_view
instead of insert
as
	declare @学号 int
	declare @姓名 varchar(20);
	declare @性别 varchar(20);
	declare @生日 varchar(20);
	declare @专业班级 varchar(20);
	select 	@学号=学号,@姓名=姓名,@性别=性别,@专业班级=专业班级
	from inserted;
	insert into 学生表(学号,姓名,性别,专业班级) values(@学号,@姓名,@性别,@专业班级);
--查看效果
insert into birth_view(学号,姓名,性别,专业班级) values(2,'阿红','女','软件04');



use market;
--第四章第五题(5)在Customers表上建立删除触发器,实现Customers表和Orders表的级联删除
select * from Customers;
select * from Orders;

create trigger customers_delete on Customers
	after delete
as
	delete from Orders
	where CustomerID in (select deleted.CustomerID FROM DELETED);

--第四章第五题(6)在Orders表上建立插入触发器,当向表中添加一条订货记录时,若订单中的商品状态为即将断货(Status='即将断货')
--则不能插入该条记录
select * from Customers;
select * from Orders;
select * from Goods;
CREATE trigger orders_insert on Orders
	AFTER INSERT
AS 
	if(select Status from Goods,inserted where Goods.GoodID=inserted.GoodID) in ('即将断货')
	begin
		print '即将断货,不能订购'
		rollback transaction
	end;
	
--试试效果
insert into Orders values(4,3,3,2,20,'2020-2-2');
--第四章第五题(7)在Orders表上建立插入触发器,当添加订单时,减少Goods表中相应商品的库存量
select * from Customers;
select * from Orders;
select * from Goods;

create trigger orders_insert1 on Orders
after insert
as 
	UPDATE Goods SET Stocks=Stocks-inserted.Quantity
	FROM Goods,inserted
	WHERE Goods.GoodID=inserted.GoodID;
	


--第四章第五题(8)在Orders表上建立触发器,不允许对订单日期进行修改
select * from Customers;
select * from Orders;
select * from Goods;
CREATE TRIGGER orders_create ON Orders
	AFTER UPDATE
as
	IF UPDATE(Date)
	BEGIN
	RAISERROR('不能手动修改',10,1)
	ROLLBACK TRANSACTION
	END;

--第四章第五题(9)建立触发器,实现参照完整性约束,即若在Orders表中添加一条记录时,则该订单中的商品也必须在
--Goods表中存在,否则不许添加该记录;
select * from Customers;
select * from Orders;
select * from Goods;

CREATE TRIGGER orders_create1 ON Orders
	AFTER INSERT
AS
	IF (SELECT COUNT(*) from Goods,inserted
		WHERE Goods.GoodId=inserted.GoodID)=0
	BEGIN
		print '这种货物不存在'
		rollback transaction
	END;

在这里插入图片描述

posted @ 2020-05-18 09:28  security9968  阅读(2799)  评论(0编辑  收藏  举报