重庆熊猫 Loading

SQL Server教程 - T-SQL-存储过程(PROCEDURE)

更新记录
转载请注明出处:https://www.cnblogs.com/cqpanda/p/16527496.html
2022年7月31日 发布。
2022年7月2日 从笔记迁移到博客。

存储过程介绍(Stored Procedure)

存储过程是什么

一种编程结构,一系列预编译的SQL语句集合,放在数据库中只用编译一次,调用不用再编译。多条SQL语句当做一个单元进行执行,存储过程也可以是.NET Framework上方法的引用组成的组。

存储过程优缺点

存储过程优点:
1、代码重用(code reuse),模块化设计。共同使用的代码可以只需要被编写一次,而被需要该代码的任何应用程序调用(.net,c++,java,也可以使DLL库)。
2、预编译执行效率高。
3、减少网络流量, 减少网络IO(reduce the amount of network IO)。
4、节省内存空间。它们以一种压缩的形式被存储在外存中,当被调用时才被放入内存进行处理。而且多个用户在调用同一个存储过程或函数时,只需要加载一次即可。
5、安全性高。可以授权客户访问存储过程而不用授权直接访问对象。提高数据的安全性和完整性。通过把一些对数据的操作方到存储过程或函数中,就可以通过是否授予用户有执行该语句的权限,来限制某些用户对数据库进行这些操作。

存储过程缺点:
1、移植性差
2、不支持面向对象
3、代码可读性差、不容易维护
4、不支持集群

存储过程适用场合

1、 如果需要返回多个值和不返回值,就使用存储过程;如果只需要返回一个值,就使用函数。
2、 存储过程一般用于执行一个指定的动作,函数一般用于计算和返回一个值。
3、 可以再SQL内部调用函数来完成复杂的计算问题,但不能调用存储过程。

存储过程和函数的区别

不同点:

  1. 存储过程用户在数据库中完成特定操作或者任务(如插入,删除等),函数用于返回特定的数据。
  2. 存储过程声明用procedure,函数用function。
  3. 存储过程不需要返回类型,函数必须要返回类型。
  4. 存储过程只能通过out和in/out来返回值,函数除了可以使用out,in/out以外,还可以使用return返回值。
  5. sql语句(DML或SELECT)中不可用调用存储过程,而函数可以。
  6. 执行方式略有不同,存储过程的执行方式有两种(1.使用execute2.使用begin和end)

相同点:

  1. 创建语法结构相似,都可以携带多个传入参数和传出参数。
  2. 都是一次编译,多次执行。

SQL Server存储过程的限制

可以引用在同一存储过程中创建的对象,只要引用时已经创建了该对象即可。
可以在存储过程中引用临时表。
如果在存储过程中创建本地临时表,则临时表仅在该存储过程中存在,退出存储过程后,
临时表将消失。
如果执行的存储过程将调用另一个存储过程,则被调用的存储过程可以访问由第一个存
储过程创建的所有对象,包括临时表。
存储过程中的参数最大数目为2100个。
存储过程的最大容量可达128MB.
存储过程中的局部变量的最大数目仅受可用内存的限制。
存储过程中不能使用下列语句:
CREATE AGGREGATE
CREATE DEFAULT
CREATE/ALTER FUNCTION
CREATE PROCEDURE
CREATE SCHEMA
CREATE/ALTER TRIGGER
CREATE/ALTER VIEW
SET PARSEONLY
SET SHOWPLAN_ALL/SHOWPLAN/TEXT/SHOWPLAN/XML
SET database_name

存储过程分类

汇总

  • 1、SQL Server自带存储过程,也称为系统存储过程。
  • 2、用户定义的存储过程。
  • 3、通过其他语言扩展的存储过程。
  • 4、临时存储过程。

系统存储

系统存储过程是指SQL Server 2019系统自身提供的存储过程,可以作为命令执行各种操作。系统存储过主要用来从系统表中获取信息,使用系统存储过程完成数据库服务器的管理工作,为系统管理员提供帮助,为用户查看数据库对象提供方便。系统存储过程位于数据库服务器中,并且以sp_开头,系统存储过程在系统定义和用户定义的数据库中,在调用时不必在存储过程前加数据库限定名。例如,前面介绍的sp_rename系统存储过程可以更改当前数据库中用户创建对象的名称;sp_helptext存储过程可以显示规则、默认值或视图的文本信息。SQL Server 2019服务器中许多的管理工作都是通过执行系统存储过程来完成的,许多系统信息也可以通过执行系统存储过程来获得。
系统存储过程创建并存放于系统数据库master中,一些系统存储过程只能由系统管理员使用,而有些系统存储过程通过授权可以被其他用户所使用。

自定义存储过程

自定义存储过程就是用户为了实现某一特定业务需求,在用户数据库中编写的 Transact-SQL语句集合,用户存储过程可以接收输入参数、向客户端返回结果和信息、返回输出参数等。创建自定义存储过程时,存储过程名前面加上“#”表示创建了一个全局的临时存储过程;存储过程名前面加上“#”时,表示创建局部临时存储过程。局部临时存储过程只能在创建它的会话中使用,会话结束时将被删除。这两种存储过程都存储在tempdb数据库中。

用户定义存储过程可以分为两类:Transact-SQL和CLR。
Transact-SQL 存储过程是指保存的Transact-SQL语句集合,可以接受和返回用户提供的参数。存储过程也可能从数据库向客户端应用程序返回数据。
CLR存储过程是指引用Microsoft.NET Framework公共语言方法的存储过程,可以接受和返回用户提供的参数,它们在。NET Framework程序集中是作为类的公共静态方法实现的。

扩展存储过程

扩展存储过程是以在SQL Server 2019环境外执行的动态链接库(DLL文件)来实现的,可以加载到SQL Server 2019实例运行的地址空间中执行,扩展存储过程可以使用SQL Server 2019扩展存储过程API来编写。扩展存储过程以前缀“xp_”来标识,对于用户来说,扩展存储过程和普通存储过程一样,可以用相同的方式来执行。

创建存储过程

创建存储过程-使用SSMS

选择新建存储过程
image

修改默认模板,然后按F5执行创建新存储过程
image

创建存储过程-使用T-SQL

使用CREATE PROCEDURE 语句创建存储过程

CREATE PROCEDURE [schema_name.] 存储过程名 [; number ]
{ @parameter data_type }
[ VARYING ] [ = default ] [ OUT | OUTPUT ] [READONLY]
[WITH <ENCRYPTION JI[ RECOMPILE ]I[ EXECUTE AS Clause ]>]
[FOR REPLICATION]
AS
BEGIN
    -- SQL语句
return @参数2; -- 可以不返回
END

procedure_name:新存储过程的名称,并且在架构中必须唯一。可在procedure_name前面使用一个数字符号(#)(#procedure_name)来创建局部临时过程,使用两个数字符号(##procedure_name)来创建全局临时过程。对于CLR存储过程,不能指定临时名称。
number:是可选整数,用于对同名的过程分组。使用一个DROP PROCEDURE 语句可将这些分组过程一起删除。例如,名称为 orders的应用程序可能使用名为 orderproc;1、orderproc;2等的过程。DROP PROCEDURE orderproc 语句将删除整个组。如果名称中包舍分隔标识符,则数字不应包含在标识符中;只应在procedure_name 前后使用适当的分隔符。
@parameter:存储过程中的参数。在CREATE PROCEDURE 语句中可以声明一个或多个参数。除非定义了参数的默认值或者将参数设置为等于另一个参数,否则用户必须在调用过程时为每个声明的参数提供值。存储过程最多可以有2100个参数。如果过程包含表值参数,并且该参数在调用中缺失,则传入空表默认值。通过将@符号用作第一个字符来指定参数名称。每个过程的参数仅用于该过程本身;其他过程中可以使用相同的参数名称。默认情况下,参数只能代替常量表达式,而不能用于代替表名、列名或其他数据库对象的名称。如果指定了 FOR REPLICATION,则无法声明参数。
date_type:指定参数的数据类型,所有数据类型都可以用作Transact-SQL存储过程的参数。可以使用用户定义表类型来声明表值参数作为Transact-SQL存储过程的参数。只能将表值参数指定为输入参数,这些参数必须带有READONLY关键字。cursor数据类型只能用于OUTPUT参数。如果指定了cursor数据类型,则还必须指定 VARYING和OUTPUT关键字。可以为cursor数据类型指定多个输出参数。对于CLR存储过程,不能指定char、varchar、text、ntext、image、cursor、用户定义表类型和table作为参数。
default:存储过程中参数的默认值。如果定义了 default 值,则无须指定此参数的值即可执行过程。默认值必须是常量或NULL.如果过程使用带LIKE关键字的参数,则可包含下列通配符:%、_、[]和[^]。
OUTPUT:指示参数是输出参数。此选项的值可以返回给调用 EXECUTE的语句。使用OUTPUT参数将值返回给过程的调用方。除非是CLR过程,否则text、ntext和image 参数不能用作OUTPUT参数。使用OUTPUT关键字的输出参数可以是游标占位符,CLR过程除外。不能将用户定义表类型指定为存储过程的OUTPUT参数。
READONLY:指示不能在过程的主体中更新或修改参数。如果参数类型为用户定义的表类型,则必须指定 READONLY.
RECOMPILE:表明SQL Server 2019不会保存该存储过程的执行计划,该存储过程每执行一次都要重新编译。在使用非典型值或临时值而不希望覆盖保存在内存中的执行计划时,就可以使用RECOMPILE选项。
ENCRYPTION:表示 SQL Server 2019 加密后的 syscomments表,该表的text字段是包含
CREATE PROCEDURE语句的存储过程文本。使用ENCRYPTION关键字无法通过查看syscomments表来查看存储过程的内容。
FOR REPLICATION:用于指定不能在订阅服务器上执行为复制创建的存储过程。使用此选项创建的存储过程可用作存储过程的筛选,且只能在复制过程中执行。本选项不能和WITH RECOMPILE选项一起使用。
AS:用于指定该存储过程要执行的操作。
sql_statement 是存储过程中要包含的任意数目和类型的Transact-SQL语句。但有一些限制。

注意:最好不要将存储过程名以sp_开头,sp是系统自带存储过程的前缀

实例:打印变量的存储过程

CREATE PROCEDURE panda_procedure
@arg1 INT = 123, @arg2 NCHAR(50)
AS
BEGIN
    PRINT @arg1;
	PRINT @arg2;
END

实例:带输出参数的存储过程

-- 定义
CREATE PROCEDURE QueryById @sID INT
AS
SELECT * FROM fruits WHERE s_id=@sID;
-- 执行
EXECUTE QueryById 101;
EXECUTE QueryById @sID1

实例:创建带默认参数的存储过程

-- 定义
CREATE PROCEDURE QueryById2 @sID INT=101
AS
SELECT *FROM fruits WHERE s_id=@sID;

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

-- 定义
CREATE PROCEDURE QueryById3
@sID INT=101,
@fruitscount INT OUTPUT
AS
SELECT @fruitscount=COUNT(fruits.s_id)
FROM fruits WHERE s_id=@sID;
-- 执行
DECLARE @fruitscount INT;
DECLARE @SID INT=101;
EXEC QueryById3 @SID, @fruitscount OUTPUT

调用存储过程-使用T-SQL

EXECUTE 存储过程名;
EXECUTE 存储过程名 实参,实参;
EXECUTE 存储过程名 @形参=实参, @形参=实参;
EXECUTE 存储过程名 实参,实参 output;
EXECUTE @RETURN_STATUS = 存储过程名 实参,实参;

注意:调用时,输出参数需要OUT修饰。

注意:EXECUTE 语句的执行是不需要任何权限的,但是操作 EXECUTE字符串内引用的对象是需要相应的权限的。例如,如果要使用 DELETE 语句执行删除操作,则调用EXECUTE 语句执行存储过程的用户必须具有DELETE权限。

存储过程内调用其他存储过程

CALL 存储过程名 实参,实参 output;

实例:

EXECUTE panda_procedure 123, N'Panda';
EXECUTE panda_procedure @arg1=123, @arg2=N'Panda';
EXECUTE panda_procedure @arg2=N'Panda',@arg1=123;

修改存储过程

修改存储过程的定义-使用T-SQL

ALTER PROCEDURE [schema_name.] 存储过程名 [; number ]
{ @parameter data_type }
[ VARYING ] [ = default ] [ OUT | OUTPUT ] [READONLY]
[WITH <ENCRYPTION JI[ RECOMPILE ]I[ EXECUTE AS Clause ]>]
[FOR REPLICATION]
AS
BEGIN
    -- SQL语句
return @参数2; -- 可以不返回
END

实例:修改存储过程

ALTER PROCEDURE [dbo].[CountProc]
AS
SELECT s_id,COUNT(*) AS 总数 FROM fruits GROUP BY s_id;

修改存储过程名-使用T-SQL

EXECUTE sp_rename '存储过程旧名', '存储过程新名';

修改存储过程名-使用SSMS

image

查看存储过程

查看存储过程定义内容-使用T-SQL

使用OBJECT_DEFINITION、sp_help 或者 sp_helptext这3个系统存储过程查看存储过程的定义信息。

EXECUTE sp_helptext '存储过程名';

实例:

EXECUTE sp_helptext 'panda_procedure';

查看所有已经定义的存储过程-使用T-SQL

SELECT * FROM sys.sql_modules;

删除存储过程

删除存储过程-使用T-SQL

DROP PROCEDURE '存储过程名';

注意:不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程

删除存储过程-使用SSMS

image

扩展存储过程

扩展存储过程是SQL Server 2019实例可以动态加载和运行的DLL。扩展存储过程是使用SQL Server 2019扩展存储过程API编写的,可直接在 SQL Server 2019实例的地址空间中运行。

SQL Server 2019中包含如下几个常规扩展存储过程:
xp_enumgroups:提供Windows本地组列表或在指定Windows域中定义的全局组列表。
xp_findnextmsg:接受输入的邮件ID并返回输出的邮件ID,需要与xp_processmail 配合使用。
xp_grantlogin:授予 Windows 组或用户对 SQL Server 2019的访问权限。
xp_logevent:将用户定义消息记入SQL Server2019日志文件和Windows事件查看器中。
xp_loginconfig: 报告 SQL Server 2019实例在Windows上运行时的登录安全配置。
xp_logininfo:报告账户、账户类型、账户的特权级别、账户的映射登录名和账户访问SQL Server 2019的权限路径。
xp_msver:返回有关SQL Server 2019的版本信息。
xp_revokelogin:撤销 Windows 组或用户对SQL Server 2019的访问权限。
xp_sprintf:设置一系列字符和值的格式并将其存储到字符串输出参数值。每个格式参数都用相应的参数替换。
xp_sqlmaint:用包含SQLMaint 开关的字符串调用SQLMaint实用工具,在一个或多个数据库上执行一系列维护操作。
xp_sscanf:将数据从字符串读入每个格式参数所指定的参数位置。
xp_availablemedia:查看系统上可用的磁盘驱动器的空间信息。
xp_dirtree:查看某个目录下子目录的结构。

posted @ 2022-07-31 08:30  重庆熊猫  阅读(2232)  评论(0编辑  收藏  举报