T-SQL 存储过程

一、概述

存储过程是为了实现某个特定任务的一组T-SQL语句的集合,这些语句形成一个完整单元并取一个名字。 存储过程在第一次执行时进行编译,然后将编译好的代码保存在高速缓存中供以后调用,需要时,在T-SQL代码中通过存储过程名字调用即可。

举个栗子:你今天要查张三的成绩,明天要查王五的成绩,对于这种需要多次执行的语句或语句组,可以封装成一个整体,起个名字 ‘”查成绩“,以后只需要调用这个名字 加上姓名就可以返回成绩,而无需每次都写一段查询语句,这就是存储过程。

1.存储过程特点:
(1)SQLServer事先将存储过程编译成可执行代码,运行存储过程时不需要再对存储过程进行编译,因此执行速度快、效率高。
(2)存储过程创建后,可以在程序中多次调用,而不必重写该T-SQL语句。
(3)存储过程存储在数据库中,可以作为一个独立的数据对象,也可以作为一个单元在数据库中被用户调用。
(4)存储过程可以接收和输出数据、参数以及返回执行存储过程的状态值,也可以嵌套使用。
(5)存储过程使开发者不必在客户端编写大量的程序代码,同时在数据库的安全性上得到提高。
2.存储过程分类:
在SQL Server中主要分为系统存储过程和用户存储过程。

  • 系统存储过程1:由系统事先定义好,用户直接调用,可以使用系统存储过程来执行许多管理和信息活动。
  • 用户存储过程:由用户自己定义。

二、创建存储过程

为方便理解,语法格式比较简化随意,如有不当还请多指教。

  1. 建立存储过程的基本语法:
    create procedure procedure_name
    [
    {@parameter data_type} [output]
    ]
    as
    sql_statement […n]

procedure 也可以简写为 proc
procedure_name 新建的存储过程的名称
parameter 过程的参数,一个存储过程可以有一个或多个参数,也可以不带。
data_type 参数的数据类型
[output] 指示参数是输出参数,将形参的值传递给对应的实参,使运算结果能够输出。

  1. 执行存储过程的语法:
    execute procedure_name [@parameter] [,…n]

execute 也可以简写为exec
procedure_name 新建的存储过程的名称
@parameter 为参数

三、修改存储过程

存储过程是一段T-SQL代码,在使用过程中,一旦发现存储过程不能完成需要的功能或者需求有变,自然是可以修改存储过程的。(当然删了重建也行趴)其语法格式为:
alter proc procedure_name
[{@partmeter data_type}] [,…n]
as
sql_statement […n]

四、删除存储过程

对于不再需要的存储过程,可以将其删除,T-SQL中可以通过 Drop Procedure语句来删除存储过程,语法格式为:drop proc procedure_name [,…n]

五、实例

1.创建数据库

create database 练习
go 
use 练习
go

create table student(
	sno char(10) primary key,
	sname char(20) not null,
	ssex char(2) check (Ssex in ('男','女')) not null,
	sage tinyint not null,
)
go 

insert student (sno, sname, ssex,sage) values('G2016001','李素素','女',19)
insert student (sno, sname, ssex,sage) values('G2016002','朱萍','女',21)
insert student (sno, sname, ssex,sage) values('G2016003','叶家裕','男',28)
insert student (sno, sname, ssex,sage) values('G2016004','邓家如','女',20)
insert student (sno, sname, ssex,sage) values('G2016005','高晓','女',21)
insert student (sno, sname, ssex,sage) values('J2016001','杨华','男',20)
insert student (sno, sname, ssex,sage) values('J2016002','刘全珍','女',22)
insert student (sno, sname, ssex,sage) values('J2016003','王国','男',21)
insert student (sno, sname, ssex,sage) values('J2016004','孙荣','男',21)
insert student (sno, sname, ssex,sage) values('J2016005','胡娟','女',20)
insert student (sno, sname, ssex,sage) values('L2016001','张茂桦','男',22)
insert student (sno, sname, ssex,sage) values('L2016002','方杰','男',21)
insert student (sno, sname, ssex,sage) values('L2016003','刘可','女',20)
insert student (sno, sname, ssex,sage) values('L2016004','黄一秋','男',21)
insert student (sno, sname, ssex,sage) values('L2016005','唐治','男',20)
insert student (sno, sname, ssex,sage) values('L2016006','韩云','男',20)
insert student (sno, sname, ssex,sage) values('S2016001','徐川','男',20)
insert student (sno, sname, ssex,sage) values('S2016002','汤洪','男',21)
insert student (sno, sname, ssex,sage) values('S2016003','马秋婷','女',20)
insert student (sno, sname, ssex,sage) values('S2016004','周英','女',20)
insert student (sno, sname, ssex,sage) values('S2016005','曹林','男',21)
go

create table course(
	cno char(10) primary key,
	cname char(30) not null,
	ccredit tinyint check (ccredit>=1 and ccredit<=10) not null,
	XKLB char(5) check (XKLB = '选修' OR [XKLB]='必修') not null
 )
go

insert course(cno, cname, ccredit,xklb) values ('B001','数据库及应用',4,'必修')
insert course(cno, cname, ccredit,xklb) values ('B002','数据结构',4,'必修')
insert course(cno, cname, ccredit,xklb) values ('B003','程序设计思想',3,'必修')
insert course(cno, cname, ccredit,xklb) values ('B004','企业文化',3,'必修')
insert course(cno, cname, ccredit,xklb) values ('B005','会计学',3,'必修')
insert course(cno, cname, ccredit,xklb) values ('B006','高等数学',2,'必修')
insert course(cno, cname, ccredit,xklb) values ('B007','线性代数',3,'必修')
insert course(cno, cname, ccredit,xklb) values ('B008','大学英语',4,'必修')
insert course(cno, cname, ccredit,xklb) values ('B009','马克思主义哲学',4,'必修')
insert course(cno, cname, ccredit,xklb) values ('X001','大学生就业指导',1,'选修')
insert course(cno, cname, ccredit,xklb) values ('X002','大学生心理指导',1,'选修')
insert course(cno, cname, ccredit,xklb) values ('X003','大学生思想修养',1,'选修')
go

create table sc(
	sno char(10) not null,
	cno char(10) not null,
	grade numeric(3, 0)check (grade>=0 and grade<=100),
	primary key(sno,cno),
	foreign key(sno)references student(sno),
	foreign key(cno)references course(cno)
)
go

insert sc (sno,cno,grade) values ('G2016001','B004',95)
insert sc (sno,cno,grade) values ('G2016001','B008',88)
insert sc (sno,cno,grade) values ('J2016001','B001',90)
insert sc (sno,cno,grade) values ('J2016003','B001',85)
insert sc (sno,cno,grade) values ('J2016005','B003',87)
insert sc (sno,cno,grade) values ('J2016001','B002',91)
insert sc (sno,cno,grade) values ('J2016004','B008',50)
insert sc (sno,cno,grade) values ('J2016004','B002',85)
insert sc (sno,cno,grade) values ('G2016003','B005',86)
insert sc (sno,cno,grade) values ('G2016003','X001',91)
insert sc (sno,cno,grade) values ('L2016001','B007',80)
insert sc (sno,cno,grade) values ('L2016002','B007',92)
insert sc (sno,cno,grade) values ('L2016004','B007',83)
insert sc (sno,cno,grade) values ('L2016005','B006',78)
insert sc (sno,cno,grade) values ('L2016001','B006',48)
insert sc (sno,cno,grade) values ('L2016006','B008',90)
insert sc (sno,cno,grade) values ('S2016001','B008',85)
insert sc (sno,cno,grade) values ('S2016002','B008',79)
insert sc (sno,cno,grade) values ('S2016003','B008',80)
insert sc (sno,cno,grade) values ('S2016001','B006',90)
insert sc (sno,cno,grade) values ('S2016004','B006',86)
insert sc (sno,cno,grade) values ('S2016005','X003',92)
insert sc (sno,cno,grade) values ('S2016003','X003',88)
insert sc (sno,cno,grade) values ('G2016002','X002',NULL)
insert sc (sno,cno,grade) values ('G2016005','X003',NULL)
go


2.举例

一般首先判断是否存在这个存储过程,用到的sys.objects目录视图。

  • 创建存储过程getGrade,通过输出参数返回指定同学指定课程的成绩。
if (exists (select * from sys.objects where name = 'getGrade'))
    drop proc getGrade
go
create proc getGrade 
@sno char(10),@cno char(20),@grade float output
as
begin
	select @grade = grade from sc
	where sno = @sno and cno = @cno
end
go

执行存储过程“getGrade”,查询学号为“G2016001”,课程号为“B008”的成绩。

declare @grade float
exec getGrade 'G2016001','B008',@grade output
print @grade
  • 编写一个名为“SelectSTUByNamePROC”的存储过程,存储过程接收一个名为“@name”的参数,存储过程的作用是根据“@name”进行模糊查询,从学生表中查询姓名中含有“@name”的学生信息。
if (exists (select * from sys.objects where name = 'SelectSTUByNamePROC'))
    drop proc SelectSTUByNamePROC
go
create proc SelectSTUByNamePROC 
@name varchar(10)
as
begin
	select *
	from student 
	where sname like '%' + @name + '%'
end
go

执行存储过程“SelectSTUByNamePROC”,查询名字中含有“家”的学生。

exec SelectSTUByNamePROC  '家'
  • 编写一个名为“UpdateSTUAgePROC”的存储过程,存储过程接收一个名为“@SNO”的参数和一个名为“@Sage”的参数,存储过程的作用是将学生表中学号为“@SNO”的学生年龄修改成“@Sage”。
if (exists (select * from sys.objects where name = 'UpdateSTUAgePROC'))
    drop proc UpdateSTUAgePROC
go
create proc UpdateSTUAgePROC 
@SNO char(10),@Sage tinyint
as
begin 
	update Student
	set Sage = @Sage
	from Student
	where Sno = @SNO
end

执行存储过程“UpdateSTUAgePROC”,将学号为“G2016002”的学生的年龄修改为19 。

exec UpdateSTUAgePROC 'G2016002','19'
  • 编写一个名为“InsertCoursePROC”的存储过程,该存储过程根据接收的参数向课程表插入一条记录。存储过程接收4个名为“@CNO”、“@CNAME”、“@CREDIT”,“@XKLB”的参数,分别代表课程号,课程名,学分,课程性质。
if (exists (select * from sys.objects where name = 'InsertCoursePROC'))
    drop proc InsertCoursePROC
go
create proc InsertCoursePROC
@CNO char(10),@CNAME char(30),@CREDIT tinyint,@XKLB char(5)
as
begin
	insert into Course(Cno,Cname,Ccredit,XKLB) values(@CNO,@CNAME,@CREDIT,@XKLB)
end

执行存储过程“InsertCoursePROC”,将课程号为“C001”,课程名为“数据库原理及应用”,学分为3,课程性质为“必修”的课程信息添加到课程表。

exec InsertCoursePROC  'C001','数据库原理及应用',3,'必修'
  • 编写一个名为“DeleteCoursePROC”的存储过程,该存储过程接收一个名为“@CNO”的参数,存储过程的作用是从课程表删除课程号为“@CNO”的课程(要求级联删除该课程号对应的选课记录)。
if (exists (select * from sys.objects where name = 'DeleteCoursePROC'))
    drop proc DeleteCoursePROC
go
create proc DeleteCoursePROC
@CNO char(10)
as
begin
	delete from SC where Cno = @CNO 
	delete from Course where Cno = @CNO
end

执行存储过程“DeleteCoursePROC”,将课程号为“B001”的课程删除。

exec DeleteCoursePROC 'B001'
  • 编写一个名为“GetMaxMinGradePROC”的存储过程,存储过程接收一个名为“@CNO”的参数,一个名为“@MAXGRADE”的输出参数和一个名为“@MINGRADE”的输出参数。存储过程的作用是使用输出参数获取课程号为“@CNO”的课程的最高分与最低分。
if (exists (select * from sys.objects where name = 'GetMaxMinGradePROC'))
    drop proc GetMaxMinGradePROC
go
create proc GetMaxMinGradePROC
@CNO char(10),@MAXGRADE numeric(3,0) output,@MINGRADE numeric(3,0) output
as
begin
select @MAXGRADE = max(grade) from sc where Cno = @CNO
select @MINGRADE = min(grade) from sc where Cno = @CNO
end

执行存储过程“GetMaxMinGradePROC”,获取课程号为“B008”的课程的最高分与最低分,并将结果输出。

declare @MAXGRADE float
declare @MINGRADE float
exec GetMaxMinGradePROC 'B008',@MAXGRADE output,@MINGRADE output
print @MAXGRADE  
print @MINGRADE

  1. 关于系统存储过程 ↩︎

猜你喜欢

转载自blog.csdn.net/m0_51086313/article/details/111656590