educoder 数据库系统概论2022 SQLServer 储存过程的创建与使用

任务描述

本关任务:学习 SQLServer 中存储过程的创建和使用。

相关知识

存储过程提供了很多 T-SQL 语言没有的高级特性,其传递参数和执行逻辑的能力,为处理各种复杂任务提供了支持。并且,由于存储过程是经过编译后,存储在服务器上的,这减少了执行过程中的传输带宽和执行时间。相反,如果使用 T-SQL ,则每次需要经过传输,再编译和执行。

什么是存储过程

存储过程是 SQLServer 中一个非常重要的数据库对象,它实际是一组为了完成特定功能的 T-SQL 语句集合。存储过程经编译后,存储在数据库中,用户通过指定存储过程的名称,并给出相应的参数,就可以对其进行执行。

SQLServer 中的存储过程具有如下特点:

  • 能够包含执行各种数据库操作的语句,并且可以调用其他的存储过程;
  • 能够接收输入参数,并以输出参数的形式,将多个数据值返回给调用程序或批处理;
  • 向调用程序或批处理,返回一个表明成功或失败(及失败原因)的状态;
  • 存储过程经过编译后,存储在数据库中,用户通过使用存储过程的名字,并指定参数来执行它。

存储过程不同于函数,存储过程不返回取代其名称的值,也不能直接在表达式中使用。

存储过程的类型

SQL Server 包含多种可用的存储过程,主要包括用户定义存储过程、扩展存储过程和系统存储过程。

用户定义存储过程

存储过程是指封装了可重用代码的模块或者例程。存储过程可以接收输入参数、向客户端返回表格或者标量结果和消息、调用数据定义语言( DDL )和数据操作语言( DML ),然后返回输入参数。
在 SQL Server 中,用户定义的存储过程有两种类型,即 T-SQL 和 CLR 。

  • T-SQL 存储过程是指保存的 T-SQL 语句集合,可以接收和返回用户提供的参数。存储过程也可能从数据库向客户端应用程序返回数据。
  • CLR 存储过程是指针对 .NET Framework 公共语言运行时方法的引用,可以接收和返回用户提供的参数。它们在 .NET Framework 程序集中,是作为类的公共静态方法来实现的。

扩展存储过程

扩展存储过程以在 SQL Server 环境外执行的动态链接库( DLL )来实现。扩展存储过程通过前缀 xp_ 来标识,它们以与系统存储过程相似的方式来执行。

系统存储过程

系统存储过程主要存储在 master 数据库中,并以 sp_ 为前缀,并且系统存储过程主要是从系统表中获取信息,从而为系统管理员 SQL Server 提供支持。通过系统存储过程, SQL Server 中的许多管理性或者信息性的活动,都可以被顺利有效地完成。

创建存储过程

在 SQL Server 中,使用 CREATE PROCEDURE 语句创建存储过程,具体的语法格式如下所示。

 
  1. CREATE { PROC | PROCEDURE } procedure_name [ ; number ]
  2. [ { @parameter data_type }
  3. [ VARYING ] [ = default ] [ OUT | OUTPUT ] [READONLY]
  4. [ WITH {RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION}]
  5. [ FOR REPLICATION ]
  6. AS { [ BEGIN ] sql_statement [;] [ ...n ] [ END ] }

简单介绍个参数的含义。

  • procedure_name 用于指定存储过程的名称;
  • number 用于指定对同名的过程分组;
  • @parameter 用于指定存储过程中的参数;
  • data_type 用于指定参数的数据类型;
  • VARYING 用于指定作为输出参数支持的结果集,仅适用于游标参数;
  • default 用于指定参数的默认值;
  • OUTPUT 用于指定参数是输出参数;
  • RECOMPILE 用于指定数据库引擎不缓存该过程的计划,该过程在运行时编译;
  • ENCRYPTION 用于指定 SQL Server 加密 syscomments 表中包含 CREATE PROCEDURE 语句文本的条目;
  • FOR REPLICATION 用于指定不能在订阅服务器上执行为复制创建的存储过程;
  • sql_statement 要包含在过程中的一个或多个 T-SQL 语句。

在命名自定义存储过程时,尽量不要使用 sp_ 作为名称前缀,避免与系统存储过程冲突。如果指定的名称与系统存储过程相同,由于系统存储过程优先级高,那么自定义的存储过程永远也不会执行。

创建简单存储过程

从 studentdb 数据库中获取学生学号、姓名和性别的存储过程。语句如下所示:

 
  1. CREATE PROCEDURE proc_getInfos
  2. AS
  3. BEGIN
  4. SELECT sno '学号', sname '姓名', sex '性别' frome student
  5. END

创建带计算函数的存储过程

统计 studentdb 数据库中,男同学个数的存储过程。语句如下:

 
  1. CREATE PROCEDURE proc_count_male
  2. AS
  3. BEGIN
  4. SELECT COUNT(*) AS '男同学' frome student where sex='男'
  5. END

创建带输入参数的存储过程

根据用户输入的姓名,得到相应的信息的存储过程。语句如下:

 
  1. CREATE PROCEDURE proc_select_where
  2. @name varchar(50)
  3. AS
  4. BEGIN
  5. SELECT * from student where sname=@name
  6. END

创建带输出参数的存储过程

创建一个存储过程,根据用户输入的年龄,返回大于输入年龄的学生有多少。语句如下:

 
  1. CREATE PROCEDURE proc_select_ret
  2. @age int,
  3. @age_count int output
  4. AS
  5. BEGIN
  6. SELECT @age_count=COUNT(*) from student where age>@age
  7. END

执行存储过程

在 SQL Server 中,可以使用 EXEC 或 EXECUTE 语句执行存储过程。

执行不带参数的存储过程

 
  1. EXEC proc_getInfos

执行带参数的存储过程

 
  1. EXEC proc_select_where '张三'

执行带输入输出参数的存储过程

 
  1. DECLARE @age_ int=19;
  2. DECLARE @count int;
  3. EXEC proc_select_ret @age_, @count output
  4. select '该班一共有'+LTRIM(STR(@count))+'人年龄大于'+LTRIM(STR(@age_));

编程要求

我们已经为你建好了数据库与数据表,并添加了相应的数据内容。
你只需:

  • 补全右侧代码片段中 create proc_student_info 下的 Begin-End 区域间的代码,实现从表中查询所有学生基本信息的存储过程(存储过程名称一定要为 proc_student_info ,测试代码将调用 proc_student_info 存储过程,下面类似);
  • 补全右侧代码片段中 create proc_sno 下的 Begin-End 区域间的代码,创建一个带参数的存储过程,输出指定学号的学生信息;
  • 补全右侧代码片段中 create proc_add 下的 Begin-End 区域间的代码,创建一个带参数的存储过程,根据指定参数增加学生信息,如果学生编号已经存在则不能增加(调用此存储过程时,会依次填充各个字段值,请注意 insert 时,参数顺序与表字段的顺序一致);
  • 补全右侧代码片段中 create student_del 下的 Begin-End 区域间的代码,创建一个带参数的存储过程,删除指定学号的学生信息。若成功,则输出 successfully deleted ;若没有该学号,则输出 No such student 。

表 student 的字段类型除了 birthday 是 date 类型,其余均为 varchar 类型,表内容如下:

测试说明

本关涉及到的测试文件是 step1.sh ,平台将运行用户补全的 step1.sql 文件,得到数据,然后执行以下操作:

  • 将得到的数据与答案比较,判断程序是否正确;

  • 如果操作正确,你将得到如下的结果:

参考代码 

USE studentdb
go

SET NOCOUNT ON 
go
--********** create proc_student_info **********--
--********** Begin **********--
create procedure proc_student_info
as 
Begin
select * from student
end



--********** End **********--
go
exec proc_student_info
go

--********** create proc_sno **********--
--********** Begin **********--
create procedure proc_sno
@sno varchar(4)
as 
Begin
select * from student where sno=@sno
end



--********** End **********--
go
exec proc_sno '1001'
go

--********** create proc_add **********--
--********** Begin **********--
create procedure proc_add
@sno varchar(4),
@sname varchar(10),
@sex varchar(10),
@birthday date,
@discipline varchar(10),
@school varchar(30)
as 
Begin
insert into student values(@sno,@sname,@sex,@birthday,@discipline,@school)
end




--********** End **********--
go
exec proc_add '1004','HMM','female','2019-6-2','English','national school'
go
exec proc_student_info
go

--********** create student_del **********--
--********** Begin **********--
create procedure student_del
@sno varchar(4)
as
Begin
if exists(select * from student where sno=@sno)
Begin
delete from student where sno=@sno
print 'successfully deleted'
end
else
print 'No such student'
end





--********** End **********--
go
exec student_del '1001'
go
exec proc_student_info
go

这里我没有做进行判断add已经存在信息的情况,但题例并不需要,按照上面的代码块既可以完成要求。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值