SQL Server——存储过程
存储过程概念
存储过程优点
存储过程的接口
存储过程的解析、编译过程
存储过程安全性
查看存储过程
加密、解密存储过程
存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(带参存储过程)来执行它。
存储过程优点

GO
IF OBJECT_ID(N'dbo.USP_GetEmployeById') IS NOT NULL
BEGIN
DROP PROC dbo.USP_GetEmployeById;
END
GO
--====================================================================================================
-- Function : 按员工号获取员工信息
-- Author : Kerry
-- Create Date : 2010-08-10
-- Description :
------------------------------------------------------------------------------------------------------
-- 2010-08-13 : 修改.......增加.....
-- 2010-08-14 : 修改.......增加.....
--====================================================================================================
CREATE PROCEDURE dbo.USP_GetEmployeById
@EmployeeID INT = -1,
@EmployeeName NVARCHAR(30) = NULL
AS
SET NOCOUNT ON;
BEGIN
IF (@EmployeeID = -1 AND @EmployeeName IS NULL)
BEGIN
PRINT '请输入员工ID号或是用户名字';
END
IF @EmployeeID = -1
SELECT * FROM dbo.Employee WHERE EmployeeName = @EmployeeName;
ELSE
SELECT * FROM dbo.Employee WHERE EmployeeID = @EmployeeID;
END
GO


代码
GO
IF OBJECT_ID(N'dbo.USP_AddEmploye') IS NOT NULL
BEGIN
DROP PROC dbo.USP_AddEmploye;
END
GO
--==========================================================================================================
-- Function : 新增一条员工记录。
-- Author : Kerry
-- Create Date : 2010-08-10
-- Description :
-------------------------------------------------------------------------------------------------------------
-- 2010-08-13 : 修改.......增加.....
-- 2010-08-14 : 修改.......增加.....
--==========================================================================================================
CREATE PROCEDURE dbo.USP_AddEmploye
@EmployeeName NVARCHAR(30),
@Sex BIT = 1,
@Department NVARCHAR(20),
@Success NVARCHAR(4) OUTPUT
AS
SET NOCOUNT ON;
BEGIN TRY
IF (@EmployeeName IS NULL OR LEN(@EmployeeName) =0)
BEGIN
PRINT ('员工姓名不能为空');
SET @Success ='失败';
RETURN;
END
INSERT INTO Employee
VALUES(@EmployeeName, @Sex, @Department)
IF @@error = 0
SET @Success ='成功';
END TRY
BEGIN CATCH
SET @Success ='失败';
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSevertiy
,ERROR_STATE() AS ErrorState
,ERROR_LINE() AS ErrorLine
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_MESSAGE() AS ErrorMessage
END CATCH
GO

你可以这样去调用、执行存储过程 ,也可以不用添加@EmployeeName这样的参数。
DECLARE @Result NVARCHAR(4);

SET @Result = '';
EXEC dbo.USP_AddEmploye
@EmployeeName ='张飞',
@Sex =1 ,
@Department = '市场部',
@Success = @Result OUTPUT
SELECT @Result;
GO

一般在执行存储过程是,最好加上架构名称,例如:dbo.USP_AddEmploye 这样可以可以减少不必要的系统开销,提高性能。 因为如果在存储过程名称前面没有加上架构名称、SQL SERVER 首先会从当前数据库sys schema开始查找,如果没有找到,则会去其它schema查找,最后在dbo架构里面查找。
存储过程的解析、编译过程
创建存储过程时,首先分析检查语法的正确性。如果在过程定义中遇到语法错误,将会返回错误,创建存储过程失败。如果语法正确,存储过程的文本将会存储在SYS.SQL_MODULES 目录视图中。
下面我们来看看一个有趣的小列子,你也可以试试。创建一个存储过程USP_GetTableTest,它里面引用了表Test,表Test根本不存在。
AS
BEGIN
SELECT * FROM TEST;
END
创建该存储过程时,不会出错,但是执行存储过程时,会爆出下面这样的错误

这是因为在存储过程创建时,它先做语法检查,如果通过了语法检查,它会尝试解析它包含的对象名,如果存在也会解析该对象引用的对象是否存在。如果引用的对象名不存在,解析会在存储过程首次执行时触发。即在首次执行存储过程时,查询处理器从 sys.sql_modules 目录视图中读取该存储过程的文本,并检查该过程所使用的对象名称是否存在。这一过程称为延迟名称解析,因为存储过程引用的表对象不需要在创建该存储过程时就存在,而只需在执行该存储过程时存在。
注意:
只有当引用的表对象不存在时才能使用延迟名称解析。所有其他对象在创建所存储的过程时必须存在。例如,引用所存储的过程中的一个现有表时,不能列出该表不存在的列。
看看下面的列子就知道了,我们先创建表TEST(col1); 然后在存储过程 USP_GetTableTest中查询它不存在的列col2

代码
GO
IF OBJECT_ID(N'USP_GetTableTest') IS NOT NULL
BEGIN
DROP PROC USP_GetTableTest;
END
GO
CREATE PROCEDURE USP_GetTableTest
AS
BEGIN
SELECT col2 FROM TEST;
END

创建存储过程时,它会报如下错误提示。

在解析阶段,Microsoft SQL Server 2005 还执行其他验证活动(例如,检查列数据类型与变量的兼容性)。如果执行存储过程时存储过程所引用的对象丢失,则存储过程在到达引用丢失对象的语句时将停止执行。在这种情况下,或在解析阶段发现其他错误时,将返回错误信息。
如果执行过程时成功通过解析阶段,则 Microsoft SQL Server 查询优化器将分析存储过程中的 Transact-SQL 语句并创建一个执行计划。执行计划描述执行存储过程的最快方法,所依据的信息包括:
表中的数据量。
表的索引的存在及特征,以及数据在索引列中的分布。
WHERE 子句条件所使用的比较运算符和比较值。
是否存在联接以及 UNION、GROUP BY 和 ORDER BY 关键字。
查询优化器在分析完存储过程中的这些因素后,将执行计划置于内存中。分析存储过程和创建执行计划的过程称为编译。优化的内存中的执行计划将用来执行该查询。执行计划将驻留在内存中,直到重新启动 SQL Server 或其他对象需要存储空间时为止。
如果随后执行了存储过程,而现有执行计划仍留在内存中,则 SQL Server 将重用现有执行计划。如果执行计划不再位于内存中,则创建新的执行计划。
存储过程安全性
在sa账号下面,执行了下面这条语句
GRANT EXECUTE ON dbo.USP_AddEmploye TO Kerry;
然后我们用Kerry这个账号登陆,往表Employee离插入一条数据

而你调用存储过程,往表Employee离插入一条数据,则如图所示

这种安全模式能让你很灵活的控制用户允许进行的活动.
查看存储过程
查看存储过程的方式很多,你可以如图所示,你可以在MSMS工具中选择“修改存储过程”或是“编写存储过程为”来查看存储过程,也可以通过查询视图,或是系统存储过程来查看你想要看的存储过程

代码
SP_HELPTEXT 'dbo.USP_GetEmployeById' --查看具体的存储过程
SELECT * FROM SYS.SQL_MODULES WHERE object_id =OBJECT_ID(N'dbo.USP_GetEmployeById') --查看具体的存储过程

加密、解密存储过程
存储过程加密一般是为了安全需要、或是保护源代码需要而加密存储过程,它一般通过关键字ENCRYPTION 来实现。SQL Server 将 CREATE PROCEDURE 语句的原始文本转换为模糊格式。模糊代码的输出在 SQL Server 2005 的任何目录视图中都不能直接显示。对系统表或数据库文件没有访问权限的用户不能检索模糊文本。但是,可通过 DAC 端口访问系统表的特权用户或直接访问数据库文件的特权用户可使用此文本。此外,能够向服务器进程附加调试器的用户可在运行时从内存中检索已解密的过程。
我们先把刚才那个存储过程加密吧

代码
GO
IF OBJECT_ID(N'dbo.USP_GetEmployeById') IS NOT NULL
BEGIN
DROP PROC dbo.USP_GetEmployeById;
END
GO
--================================================================================================
-- Function : 按员工号获取员工信息
-- Author : Kerry
-- Create Date : 2010-08-10
-- Description :
--------------------------------------------------------------------------------------------------
-- 2010-08-13 : 修改.......增加.....
-- 2010-08-14 : 修改.......增加.....
--================================================================================================
CREATE PROCEDURE dbo.USP_GetEmployeById
@EmployeeID INT = -1,
@EmployeeName NVARCHAR(30) = NULL
WITH ENCRYPTION
AS
SET NOCOUNT ON;
BEGIN
IF (@EmployeeID = -1 AND @EmployeeName IS NULL)
BEGIN
PRINT '请输入员工ID号或是用户名字';
END
IF @EmployeeID = -1
SELECT * FROM dbo.Employee WHERE EmployeeName = @EmployeeName;
ELSE
SELECT * FROM dbo.Employee WHERE EmployeeID = @EmployeeID;
END
GO

执行以后,你可以看见加密过后的存储过程,它的图标多了个小锁,而且你再也不能通过上面查看存储过程的方式来查看存储过程了。使用MSMS查看则会弹出下面错误提示

而用SP_HELPTEXT 则提示:对象 'dbo.USP_GetEmployeById' 的文本已加密。
SQLServer2005里使用WITH ENCRYPTION选项创建的存储过程仍然和sqlserver2000里一样,都是使用XOR进行了的加密。和2000不一样的是,在2005的系统表syscomments里已经查不到加密过的密文了。要查密文必须使用DAC(专用管理员连接)连接到数据库后,如果你接手了数据库管理,里面有些存储过程加密了,你又没有创建加密存储过程的那些脚本,你是否干着急啊。别急,呵呵,网上有位叫王成辉翻译整理了国外大牛写的解密加密存储过程的一个存储过程usp_decrypt。呵呵,有兴趣的可以找来看看,我在SQL SERVER 05下面实验过了,确实能解密已经被加密的存储过程。
SQL Server——存储过程的更多相关文章
- SQL Server存储过程中使用表值作为输入参数示例
这篇文章主要介绍了SQL Server存储过程中使用表值作为输入参数示例,使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据,这样 ...
- SQL Server存储过程Return、output参数及使用技巧
SQL Server目前正日益成为WindowNT操作系统上面最为重要的一种数据库管理系统,随着 SQL Server2000的推出,微软的这种数据库服务系统真正地实现了在WindowsNT/2000 ...
- SQL Server 存储过程(转载)
SQL Server 存储过程 Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这 ...
- 14、SQL Server 存储过程
SQL Server 存储过程 存储过程类似函数,可以重复使用.相对于函数,存储过程拥有更强大的功能和更高的灵活性. 存储过程中可以包含逻辑控制语句和数据操作语句,可以接受参数,输出参数,返回单个值或 ...
- (摘录)SQL Server 存储过程
文章摘录:http://www.cnblogs.com/hoojo/archive/2011/07/19/2110862.html SQL Server 存储过程 Transact-SQL中的存储过程 ...
- Sql Server 存储过程中查询数据无法使用 Union(All)
原文:Sql Server 存储过程中查询数据无法使用 Union(All) 微软Sql Server数据库中,书写存储过程时,关于查询数据,无法使用Union(All)关联多个查询. 1.先看一段正 ...
- Yii2.0调用sql server存储过程并获取返回值
1.首先展示创建sql server存储过程的语句,创建一个简单的存储过程,测试用. SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE P ...
- C# 调用存储过程 Sql Server存储过程 存储过程报错,程序中的try
C#程序调用Sql Server存储过程,存储过程中报错情况,返回值... 0.SQL存储过程 USE [Opos] GO /****** Object: StoredProcedure [dbo]. ...
- sql server 存储过程使用游标记录
sql server 存储过程使用游标记录--方便下次参考使用 游标的组成: 声明游标 打卡游标 从一个游标中查找信息 关闭游标 释放游标 游标类型: 静态游标 动态游标 只进游标 键集驱动游标 静态 ...
- SQL Server存储过程输入参数使用表值
转载自:http://blog.csdn.net/smithliu328/article/details/9996149 在2008之前如果我们想要将表作为输入参数传递给SQL Server存储过程使 ...
随机推荐
- 6、ABPZero系列教程之拼多多卖家工具 框架后台的设置
接着上篇文章,现在去修改注册登录逻辑代码还为时过早,我们还需要到后台去设置一些配置. 管理---设置 先配置好这2项设置,邮箱配置是为了验证注册时功能是否正常,下一篇文章需要用到. 注:邮箱配置中的密 ...
- C# Main函数详解
2018-01-15 22:10:59 一.Main()方法的简介 1.唯一性.一般情况下,一个C#可执行程序只有一个Main函数,作为程序入口.但是在某些情况(如单元测试中),程序拥有多个Main ...
- Java的参数传递是值传递还是引用传递
当一个对象被当作参数传递到一个方法后,在此方法内可以改变这个对象的属性,那么这里到底是值传递还是引用传递? 答:是值传递.Java 语言的参数传递只有值传递.当一个对象实例作为一个参数被传递到方法中 ...
- 合并 CentOS 6.8 的两个ISO镜像
合并 CentOS 6.8 的两个ISO镜像 1.创建相关目录: [root@local ~] mkdir -p /mnt/dvd1 /mnt/dvd2 /mnt/dvd3 /mnt/iso 说明: ...
- 多个tab选项卡
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- LVS三种模式分析(超详细)
1.DR模式:(Direct Routing)直接路由模式 DR模式的网络拓扑: DR模式的工作过程: 1.当一个client发送一个WEB请求到VIP,LVS服务器根据VIP选择对应的real-se ...
- Memcache缓存
memcache 是服务器缓存系统,以键值对方式保存数据到内存中,把对象序列化后,理论上可支持所有的数据类型.使用情景:怎么用都可以,注意的是它只把数据保存到内存中,重启memcache 服务后丢失, ...
- Eclipse导入Hadoop源码项目及编写Hadoop程序
一 Eclipse导入Hadoop源码项目 基本步骤: 1)在Eclipse新建一个java项目[hadoop-1.2.1] 2)将Hadoop压缩包解压目录src下的core,hdfs,mapred ...
- Open-air shopping malls(二分半径,两元交面积)
http://acm.hdu.edu.cn/showproblem.php?pid=3264 Open-air shopping malls Time Limit: 2000/1000 MS (Jav ...
- HDU--2015
偶数求和 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...