数据库23:SQLServer 储存过程的创建与使用(头歌云课)

 

  • 任务描述
  • 相关知识
    • 什么是存储过程
    • 存储过程的类型
      • 用户定义存储过程
      • 扩展存储过程
      • 系统存储过程
    • 创建存储过程
      • 创建简单存储过程
      • 创建带计算函数的存储过程
      • 创建带输入参数的存储过程
      • 创建带输出参数的存储过程
    • 执行存储过程
      • 执行不带参数的存储过程
      • 执行带参数的存储过程
      • 执行带输入输出参数的存储过程
  • 编程要求
  • 测试说明

任务描述

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

相关知识

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

数据库23:SQLServer 储存过程的创建与使用(头歌云课)_第1张图片

什么是存储过程

存储过程是 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 语句创建存储过程,具体的语法格式如下所示。

CREATE { PROC | PROCEDURE } procedure_name [ ; number ]
[ { @parameter data_type }
[ VARYING ] [ = default ] [ OUT | OUTPUT ] [READONLY]
[ WITH {RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION}]
[ FOR REPLICATION ]
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 数据库中获取学生学号、姓名和性别的存储过程。语句如下所示:

CREATE PROCEDURE proc_getInfos
AS
BEGIN
SELECT sno '学号', sname '姓名', sex '性别' frome student
END

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

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

CREATE PROCEDURE proc_count_male
AS
BEGIN
SELECT COUNT(*) AS '男同学' frome student where sex='男'
END

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

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

CREATE PROCEDURE proc_select_where
@name varchar(50)
AS
BEGIN
SELECT * from student where sname=@name
END

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

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

CREATE PROCEDURE proc_select_ret
@age int,
@age_count int output
AS
BEGIN
SELECT @age_count=COUNT(*) from student where age>@age
END

执行存储过程

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

执行不带参数的存储过程

EXEC proc_getInfos

执行带参数的存储过程

EXEC proc_select_where '张三'

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

DECLARE @age_ int=19;
DECLARE @count int;
EXEC proc_select_ret @age_, @count output
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 类型,表内容如下:

数据库23:SQLServer 储存过程的创建与使用(头歌云课)_第2张图片

测试说明

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

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

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

数据库23:SQLServer 储存过程的创建与使用(头歌云课)_第3张图片


 

开始你的任务吧,祝你成功!

实验代码

USE studentdb
go

SET NOCOUNT ON 
go
--********** create proc_student_info **********--
--********** Begin **********--
create proc proc_student_info
as
begin
select * from student
end
--********** End **********--
go
exec proc_student_info
go

--********** create proc_sno **********--
--********** Begin **********--
create proc proc_sno
@sno varchar(50)
as
begin 
select * from student where sno=@sno
end
--********** End **********--
go
exec proc_sno '1001'
go

--********** create proc_add **********--
--********** Begin **********--
create proc proc_add
@sno varchar(50),
@sname varchar(50),
@sex varchar(10),
@date date,
@dis varchar(50),
@school varchar(50)
as
begin 
if EXISTS(SELECT * FROM student WHERE sno=@sno)
print 'Already have a primary key '+@sno
else
insert into student values(@sno,@sname,@sex,@date,@dis,@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 PROC student_del
@sno varchar(50)
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

 

 

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