560 likes | 647 Views
数据库系统概论 An Introduction to Database System 第八章 数据库编程 (2). 存储过程( Stored Procedures ). 8.2 存储过程简介 存储过程 (Stored Procedure) 可以使得对数据库的管理、以及显示关于数据库及其用户信息的工作容易得多。 存储过程是 SQI 语句和可选控制流语句的预编译集合,以一个名称存储并作为一个单元处理。 存储过程存储在数据库内,可由应用程序通过一个调用执行,而且允许用户声明变量,有条件执行以及其他强大的编程功能。
E N D
数据库系统概论 An Introduction to Database System 第八章 数据库编程(2)
8.2 存储过程简介 存储过程(Stored Procedure)可以使得对数据库的管理、以及显示关于数据库及其用户信息的工作容易得多。存储过程是SQI语句和可选控制流语句的预编译集合,以一个名称存储并作为一个单元处理。存储过程存储在数据库内,可由应用程序通过一个调用执行,而且允许用户声明变量,有条件执行以及其他强大的编程功能。 存储过程可包含程序流、逻辑以及对数据库的查询。它们可以接受参数,输出参数、返回单个或多个结果集以及返回值。 存储过程是封装重复性工作的一种方法。存储过程支持用户声明的变量、条件执行和其他有用的编程功能。
SQL Sever支持以下5种类型的存储过程: 系统存储过程(Sp) 存储在Master数据库中,系统存储过程(由Sp_ Prefix标识)提供了一种有效的方法检索来自系统表的信息。 系统存储过程主要是从系统表中获取信息,允许系统管理员执行更新系统表的数据库管理工作;即使管理员没有直接更新底层表的许可权,尽管这些系统存储过程被放在Master数据库中,但是仍可以在其他数据库中对其进行调用.在调用时不必在存储过程名前加上数据库名,而且当创建一个新数据库时,这些系统存储过程会在新数据库中被自动创建。 本地存储过程 本地存储过程在独立的用户数据库中被创建。
临时存储过程 临时存储过程可以是本地的,名字以单个数字符号(#)开始;或 是全局的,名字以双数字开始(##)。本地临时存储过程在单个用户任务中有效全局临时存储过程在所有用户任务中都有效。 远程存储过程 远程存储过程是SQL Server早期的功能。现在,分布查询支持该功能。 扩展存储过程 扩展存储过程作为在SQL Server环境外被执行的动态链接库来实 现,扩展存储过程通过xp前缀被标识。它们以与存储过程相似的方式被执行。 存储过程可作为一种安全机制来充分利用
8.2 .1 存储过程的初始化和后续处理 存储过程的初始化 处理一个存储过程包括首次创建并执行它,存储过程将其执行规划放置在缓存中。过程缓存是一个内存池,包含了当前要执行的所有T-SQL的执行规划。过程缓存的大小根据活动级别自动变化,它位于SQl主要的记忆单元——内存池中,包含了在SQLS的中使用内存的大多数数据结构。 在存储过程被创建时,其中的语句要进行语法分析,检查语法的准确性,然后Sysobjects把存储过程的名字存放在当前数据库的Sysobjects系统表中,把存储过程的文本存放在Syscomments系统表中。如果遇到语法错误将返回错误信息,并且该存储过程也不会被创建。
称为延时名字解析的处理允许存储过程引用在创建存储过程时不存在的对象。该处理具有灵活性,因为它参照的存储过程和对象没必要以特定的顺序创建。但是在存储过程执行时,参照的对象就必须存在。 第一次执行存储过程或存储过程必须被重编译时,在称为解析的处理过程中查询处理器读取存储过程。 某些在数据库中产生的变化会导致存储过程的执行规划无效或不再可用。在以下情况SQL Server将删除这些变化并重编译执行规划
存储过程引用的表中或查询参照的视图中(ALTERTABLE和ALTERVIEW)产生了任何结构变化。存储过程引用的表中或查询参照的视图中(ALTERTABLE和ALTERVIEW)产生了任何结构变化。 新的分布统计产生,要么明确地来自语句,例如UPDATESTATISTICS,要么自动产生. 存储过程的执行规划使用的索引被删除. 大量的变化发生在存储过程的查询所参照韵表的关键字中(1NSERT语句或DELETE语句 ). 在存储过程成功地通过了解析阶段后,SQL Server查询优化器分析在存储过程中的Transact-SQL,并且创建一个包含访问数据最快方法的计划。
存储过程的后续处理 存储过程的后续处理比初始处理快,因为SQL Server使用存储过程高速缓存中的查询计划 如果适用以下条件,SQL Server使用内存中的存储过程计划: 当前环境与计划被编译的环境相同。服务器、数据库和连接设置确定该环境。 存储过程引用的对象不要求名字辨析。当由不同用户拥有的对象有相同的名字时, 对象要求名字辨析
例如,如果Sales角色拥有Products表,Development角色拥 有Products表,SQLServer在每次引用Products表时,必须确定操作于哪个表。 过程高速缓存含有最近最多使用的(MRU)查询计划,当新的存储过程执行时,如果内存不够,则SQL Server替换最近最少使用的(LRU)查询计划。
语法 CREATE PROC [EDURE] procedure_ name[;number] [{@parameter data_type} [=default] [OUTPUT] ] [ ,...n ] [WITH {RECOMPILE | ENCRYPTION | RECOMPILE,ENCRYPTION}] [FOR REPLICATION] AS sql_statement[,...n]
各参数的含义如下: Procedure_Name新存储过程的名称。对于数据库及其所有者必须惟一。要创建局部临时过程,可以在Procedure_ Name前面加一个编号符#(#Procedure_Name),要创建全局临时过程,可以在Procedure Name前面加两个编号符#(#Procedure_Nme)。完整的名称(包括#或##)不能超过128 个字符。指定过程所有者的名称是可选的. Number是可选的整数,用来对同名的过程分组, 以便用一条DROP PROCEDURE语句即可将同组的过程一起除去。例如,名为Orders的应用程序使用的过程可以命名Orderproc;1,Orderproc;2等。 DROP PROCEDURE orderproc 语句将除去整个组。如果名称中包含定界标识符,则数字不应包含在标识符中,只应在Procedure_ Name前后使用适当的定界符。
@Parameter过程中的参数。在CREATEPROCEDURE语句中可以声明一个或多 个参数。用户必须在执行过程时提供每个所声明参数的值(除非定义了该参数的默认值).存储过程最多可以有2100个参数。使用@符号作为第-下个字符来指定参数名称。参数名称必须符合标识符的规则。每个过程的参数仅用于该过程本身;相同的参数名称可以用在其他过程中。默认情况下,参数只能代替常量,而不能用于代替表名、列名或其他数据库对象的名称.; Data_Type参数的数据类型。所有数据类型(包括Text、Ntext和Image)均可 以用作存储过程的参数. Default参数的默认值。如果定义了默认值,不必指定该参数的值即可执行过程。默认值必须是常量或NULL。如果过程将对该参数使用LIKE关键字,那么默认值中可以包含通配符(% ,_,[]和[^])
OUTPUT表明参数是返回参数。该选项的值可以返回给EXEC[UTE]。使用OUTPUT参数可将信息返回给调用过程。Text,Ntext和image参数可用作OUTPUT参数.OUTPUT表明参数是返回参数。该选项的值可以返回给EXEC[UTE]。使用OUTPUT参数可将信息返回给调用过程。Text,Ntext和image参数可用作OUTPUT参数. [...n]表示最多可以指定2100个参数的占位符. {RECOMPILE| ENCRYPTION |RECOMPILE, ENCRYPTION} RECOMPILE 表 明SQL Server不会缓存该过程的计划,该过程将在运行时重新编译。在使用非典 型值或临时值而不希望覆盖缓存在内存中的执行计划时,请使用RECOMPILE 项。ENCRYPTION表示SQL Server加密,Syscomments表中包含CREATE PROCEDURE语句文本的条目。使用ENCRYPTION可防止将过程作为SQL Server 复制的一部分发布.
FOR REPLICATION指定不能在订阅服务器上执行为复制创建的存储过程。使用FORREPLICATION选项创建的存储过程可用作存储过程筛选,且只能在复触过程中执行。本选项不能和WITHRECOMPILE选项一起使用。 AS指定过程要执行的操作。 Sql_Statement过程中要包含的任意数目和类型的Transact-SQL语句。但有一些限 [...n]是表示此过程可以包含多条Transact-SQL语句的占位符. 应该指出一个存储过程的最大尺寸为128M.,虽然一般情况下我们并不需要使用这大的空间,但是它能支持的大一些总是好的,说不定什么时候会用到。另外用户定义的矿储过程必须创建在当前数据库中.
例8.2 使用带有复杂SELECT语句的简单过程。下面的存储过程从四个表的连接中返回所有作者(提供了姓名)、出版的书籍以及出版社.该存储过程不使用任何参数.
USE pubs IF EXISTS (SELECT name FROM Sysobjects WHERE name ='au_info' AND type ='P') DROP PROCEDURE au_ info G0 CREATE PROCEDURE au_info AS SElECT au_1name,au_fname, title, pub_name EROM authors a INNER JOIN titleauthor ta 0N a.au_id = ta.au_id INNER JOIN titles t 0N t.title_id = ta.title_id INNER JOIN publishers p 0N t.pub_id = p.pub_id
因为存储过程会在sysobjects表中占一行,所以例8.1中首先检查是否存在名为au_info的存储过程,如果存在则删除此存储过程.因为存储过程会在sysobjects表中占一行,所以例8.1中首先检查是否存在名为au_info的存储过程,如果存在则删除此存储过程. 我们可以执行以下语句检查存储过程的结果: EXEC au_infO 结果其实就是AS后的多表查询的结果.
8.2.3执行存储过程 执行标量值的用户定义函数、系统过程、用户定义存储过程或扩展存储过程同时支持Transact-SQL批处理内的字符串的执行。 语法 执行存储过程: [[EXEC[UTE.]] { [@return status=] {procedure_name[;number] | @procedure_ name_ var ) [[@parameter=]{value | @variable[OUTPUT.] | [DEFAULT]] [ ,...n ] [WITH RECOMPILE]
执行字符串: EXEC[UTE]({@string_variable |[N] 'tsql_string')[十...n]) 参数 @Return Status是一个可选的整型变量,保存存储过程的返回状态。这个变量在 用于execute语句前,必须在批处理、存储过程或函数中声明过. Procedure Name是将调用的存储过程名称。这个过程名称必须符合标识符规则, 用户可以执行在另一数据库中创建的过程,只要该用户拥有此过程或有在该数据库中执行它的适当的权限。用户可以在另一台运行SQL Server的服务器上执行过程,只要该用户有适当的权限使用该服务器(远程访问),并能在数据库中执行该过程。如果指定了服务器名称但没有指定数据库名称,SQL Server会在用户默认的数据库中寻找该过程.
Number是可选的整数,用于将相同名称的过程进行组合,使得它们可以用一句DROPPROCEDURE语句除去。该参数不能用于扩展存储过程。在同一应用程序中使用的过程一般都以该方式组合。例如,在订购应用程序中使用的过程可以Orderproc;1,Orderproc;2等来命名。DROPPROCEDUREorderproc语句将除去整 个组。在对过程分组后,不能除去组中的单个过程. @Procedure_ Name_ Var.是局部定义变量名,代表存储过程名称。 @Parameter是过程参数,在CREATE.PROCEDURE语句中定义。参数名称前必须加上符号(@)。在以 @Parameter_Name=Value格式使用时,参数名称和常量不 一定按照CREATEPROCEDURE语句中定义的顺序出现。但是,如果有一个参数使用@ParameterName=Value格式,则其他所有参数都必须使用这种格式
Value是过程中参数的值。如果参数名称没有指定,参数值必须以CREATE PROCEDURE语句中定义的顺序给出。如果参数值是一个对象名称,字符串或通过数据库名称或所有者名称进行限制,则整个名称必须用单引号括起采。如果参数是一个关键字,则必须用双引号括起来。 [,.n]是占位符,表示在它前面的项目可以多次重复执行. WITHRECOMPILE强制编译新的计划。如果所提供的参数为非典型参数或者数据有很大的改变,使用该选项。在以后的程序执行中使用更改过的计划。该选项不能用于扩展存储过程。建议尽量少使用该选项,因为它消耗较多系统资源.
char,Varchar Nchar或Nvarchar数据类型,最大值为服务器的可用内存。如果字符串长度超 过4,000个字符,则把多个局部变量串联起来用于EXECUTE字符串。 [N]TsqL_string, 是一个常量,Tsql_String可以是Nvarchar或Varchar数据类型, 如果包含N,则该字符串将解释为Nvarchar数据类型,最大值为服务器的可用内存。如果字符串长度超过4,000个字符,则把多个局部变量串联起来用于 EXECUTE字符串。
例8.3:使用多个输入参数与一个输出参数。 IF EXISTS(SELECT name FROM sysobjects WHERE name=‘strconnect’AND type=‘P’) DROP PROCEDURE strconnect GO CREATE PROC strconnect @a varchar(10),@b varchar(10),@result varchar(20) output AS SET@result=@a+@b
执行此储存过程:我们提供3个字符串来执行这一存储过程。执行此储存过程:我们提供3个字符串来执行这一存储过程。 DECLARE@result varchar(20),@a varchar(10),@b varchar(10) SET@a=‘I am’ SET @b=‘lfm’ EXECUTE strconnect @a,@b,@result output SELECT ‘The result’=@result 结果 The result I am lfm (所影响的行数为1行)
例8.4:检查指定作者所在州的ID。如果所在的州是加利福尼亚州(CA),将返回状态代码置1。否则,对于任何其他情况(state的值是CA以外的值或者au_id没有匹配的行),将返回状态代码2。例8.4:检查指定作者所在州的ID。如果所在的州是加利福尼亚州(CA),将返回状态代码置1。否则,对于任何其他情况(state的值是CA以外的值或者au_id没有匹配的行),将返回状态代码2。 CREATE PROCEDURE checkstate @param varchar(11) AS IF(SELECT state FROM authors WHERE au_id= @param)='CA' RETURN 1 ELSE RETURN 2
显示从checkstate执行中返回的状态。第一个显示的是在加利福尼亚州的作者。第2个显示的是不在加利福尼亚州的作者,第3个显示的是无效的作者。必须先声明@return_status局部变量后才能使用它。显示从checkstate执行中返回的状态。第一个显示的是在加利福尼亚州的作者。第2个显示的是不在加利福尼亚州的作者,第3个显示的是无效的作者。必须先声明@return_status局部变量后才能使用它。 DECLARE @return_ status int EXEC @return_ status= checkstate '172—32—1176' SELECT 'Return Status’= @return status GO 结果 Return Status 1
Returning Values with Output Parameters • CREATE PROCEDURE dbo.mathtutor • @m1 smallint, • @m2 smallint, • @result smallint OUTPUT • AS • SET @result = @m1 * @m2 • DECLARE @answer smallint • EXECUTE mathtutor 5, 6, @answer OUTPUT • SELECT 'The result is: ' , @answer • The result is: 30 Creating Stored Procedure Executing Stored Procedure Results of Stored Procedure
Executing Stored Procedures with Input Parameters • Passing Values by Reference • Passing Values by Position EXEC addadult @firstname = 'Linda', @lastname = 'LaBrie', @street = 'Dogwood Drive', @city = 'Sacramento', @state = 'CA', @zip = '94203' EXEC addadult 'LaBrie', 'Linda', null,'Dogwood Drive', 'Sacramento', 'CA','94203', null
8.2.4 修改存储过程 • 存储过程被创建以后如果要修改也可以用两种方法: • Transact-SQL语句, • 企业管理器.
利用Transact-SQL语句修改 修改用CREATEPROCEDURE命令创建的存储过程,并且不改变权限的授予情况,以及不影响任何其他的独立的存储过程或触发器,常使用ALTER PROCEDURE命令。
语法 ALTER PROC [ EDURE ] procedure_name [ ; number ] [ { @parameter data_type ) [ = default ] [ OUTPUT ] ] [ ,...n ] [ WITH { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTI0N } [ FOR REPlICATI0N ] AS Sql_Statement [ ...n ]
参数、 Procedure_Name.是要更改的过程的名称。过程名称必须符合标识符规则; Number是现有的可选整数,该整数用来对具有同一名称的过程进行分组,以便可以用一条DROP PROCEDURE语句全部除去它们; @Parameter 过程中的参数; Data_Type是参数的数据类型; Default 参数的默认值; . OUTPUT 表明参数是返回参数; [...n]表示最多可指定2100个参数的占位符;
{RECOMPILE | ENCRYPTION | RECOMPILE,ENCRYPTION} RECOMPILE表明SQL_ Server不会高速缓存该过程的计划,该过程将在运行时重新译,ENCRYPTION表示SQL_Server加密Syscomments表中包含ALTER PROCEDURE 语句文本的条目。使用ENCRYPTION可防止将过程作为SQL Server复制的一部分发布. FOR REPLICATION指定不能在订阅服务器上执行为复制创建的存储过程。使用FOR REPLICATION选项创建的存储过程可用作存储过程筛选,且只能在复制 过程中执行。本选项不能和WITH RECOMPILE选项一起使用; AS过程将要执行的操作; Sql_Statement过程中耍包含的任意数目和类型的Transact-SQL语句。但有一些限制。
例8.5:修改存储过程. 1 先创建一个存储过程,该存储过程获取所有居住在加里福尼亚奥克兰城的作者的信息. IF EXISTS(SELECT name FROM sysobjects WHERE name='oakland_authors'AND type='P’) 8.2.5 重新命名存储过程 . 修改存储过程的名字使用系统存储过程Sp_Rename 其命令格式为: Sp_Rename 原存储过程名,新存储过程名 例8.6:把例8.5存储过程名’Oakland_ Authors更改为Newname . EXEC sp_rename Oakland_authors,Newname
8.2.6 删除存储过程 删除存储过程使用drop命令,drop命令可将一个或多个存储过程或者存储过程组从当前数据库中删除. 其语法规则为: DROP PROCEDURE{procedure} [,...n] 例8.7:将存储过程newname从数据库中删除。 DROP PROCEDURE newname GO
8.2.7系统和扩展存储过程 Microsoft大量使用元数据的概念。对于SQL Server, 元数据就是服务器中对象的信息, 如数据库文件有多大,用户有什么权限。需要改变和读取这些系统信息时,可以直接打开系统表,在其中寻找所要的数据,但系统表中的大部分数值都不容易理解(大部分都是难以译码的数字)。一个更好的方法是利用系统存储过程
每次增加数据库, 增加登录(提供对SQL Server的访问)、 生成索引和 增加或修改服务器中的任何对象时, 就要改变系统表,SQL Server在表中存放关于对象的信息。这些系统表中存放的信息大部分是数字数据,很难直接阅读,更不用说修改。因此SQL Server提供了大量(大约650个)存储过程,可以帮助修改系统表, 它们都存放在master和msdb数据库中,大部分以字符sp_开头。
最常用的系统存储过程 Sp_Tables:这个存储过程显示SELECT查询FROM从句中可用的对象,在忘记 或不知道要查询的表或视图名称时很有用; Sp_Stored_Procedure:这个存储过程列出所有可用的存储过程,在忘记或不知道所要的存储过程名称时有用; Sp_Server_Info这个过程确定SQL Server安装时的配置,如安装时定义的字符集和排序顺序,运行的SQL Server版本(如桌面或标准)等等; Sp_Databases列出服务器上所有可用的数据库,用于寻找数据库名; Sp_Start_Job用于在SQL Server中启动自动化作业,对实时计划的作业非常但要提供作业名参数;
Sp_Stop_Job这个存储过程停止已经启动的作业; Sp_Addlogin 这个存储过程在服务器中增加标准登录名,使用户访问整个服务 器。这对生成系统崩溃时重建用户登录名的脚本非常有用; Sp_Grantlogin 用于SQL Server中向Windows NT账号提供访问权限,应与Sp_Addlogin账号组合,生成系统崩溃时重建用户登录名的脚本; Sp_Setapprole SQL Server中的账号角色保证只有批准的应用程序用于访问 数据库,这个存储过程激活应用程序角色,使用户能使用应用程序角色的权限访问
Sp_Password 标准登录与SQLServer登录所用账号有所不同,这个存储过程对标准登录改变口令; Sp_Attach_Db SQL Server中的所有数据库都在主数据库的Sysdatabases系统表 中有记录。这个记录告诉SQLServer数据库是否在磁盘上,有多大,等.如果 丢失主数据库且没有备份,要运行该存储过程,对服务器中的每个数据库重建Sysdatabases 系统表。可以利用它实现数据库的转移; Sp_Processmail SQL Server不仅能够发送,而且可以接收和响应E-Mail。配置SQLMail时,可以通过E-Mail将查询发送到SQLServer服务中。运行这个存储 过程时,SQLServer服务读取E-Mail中的查询,并返回结果集;
Sp_Monitor 这个存储过程提供服务器工作的瞬像,如处理器多忙,使用多少内存等; Sp_Who用于了解谁在用数据库,以便切断他进行维护工作; Sp_Rename 改变数据库中任何对象的名称; Sp_Help用于寻找数据库的任何对象的信息; Sp_Helptext 用于显示生成数据库对象时使用的实际文本,这个信息从Syscomments表中读取; Sp_Help* 许多存储过程的名称以Sp_Help开头,提供数据库中某种对象的特定信息,这些系统存储过程的用法和任何其他存储
举一个例子: 从Start菜单Programs组的SQL Server 2000组中选择Query Analyzer将其打开,用 Windows NT Authentication登录(除非必须用SQL Server Authentication); 2 为用Sp_Help取得pubs数据库中的Authors 表的信息,输入并执行下列代码: Use Pubs EXEC SP Help 'authors' 3 为显示SQL Serve的工作情况,用Sp_Monitor存储过程: EXEC SP_ MONITOR 4 关闭Query Analyzer
8.2.8 使用扩展存储过程 另一种存储过程是扩展存储过程。扩展存储过程扩展了SQL Server的功能,使其能做数据库服务器通常无法完成的工作。例如,数据库服务器无法从命令提示下执行命令,但利用SQL Server所带的扩展存储过程Xp_Cmdshell,就可以利用语句执行CMD命令。 扩展存储过程就是存放成动态链接库(Dynamic Link Library(OLL))的C代码, 以DLL执行。大多数扩展存储过程和其他系统存储过程一起执行,很少单独使用。但下列 扩展存储过程有可能单独使用:
Xp_ Cmdshell 这个存储过程运行通常从命令提示下执行的命令,如DIR和Md(改变目录)。这在要求SQL Server生成自动存档BCP文件或这类内容的目录时非常方便。 Xp_ Fileexist 这个过程可以测试文件是否存在,如果存在,可以进行一些操作(如BCP)。后面的代码显示如何测试Autoexee.Bat文件是否存在,如果@Ret=1,则,文件存在;如果等于0,则文件不存在。这在BooksOnline或MicrosoftWeb站点 中没有建档,因此这里给出它的语法。第一行声明保存输出参数的变量,第二行调用带输出参数的过程,第三行显示输出(注意这应在主数据库中进行)。 Xp Fixeddrives 显示硬盘的盘号和可用MB数。
例 1 从Start菜单Programs组的MSSQLServer组中打开QuexyAnalyzer,并用WindowsNT Authentication登录。为用xp_cmdshell取得C盘inetpub的目录清单,输入井执行下列 代码: EXEC xp_cmdshell ‘dir c:\inetpub’ 2 为显示autoexec.bat文件是否在C盘中,输入并执行下列代码: DECLARE@ret int EXEC xp_fileexist ‘c:\autoexec.bat’@ret output SELECT @ret
Executing Extended Stored Procedures • Increase SQL Server Functionality • Are Programmed Using Open Data Services API • Can Include C and C++ Features • Can Contain Multiple Functions • Can Be Called from a Client or SQL Server • Can Be Added to the master Database Only EXEC master..xp_cmdshell 'dir c:\mssql7'
8.2.9处理错误信息 为了保证存储过程的有效性,应包含告诉用户事务状态(成功或失败)的错误信息’应尽量保持事务很短。 可以使用编码策略来识别错误,如存在检查。当发生错误时,给客户应用程序提供尽可能多的信息。可以在错误处理逻辑中检查返回代码、SQL Server错误和自定义错误信息。 RETURN语句 RETURN无条件从查询或过程中退出,它还返回一个整数状态值(返回代码)。除非特别指明,所有系统存储过程返回0值表示成功,返回非零值则表示失败。如果不提供用户定义的返回值,使用SQL Server值。用户定义的返回值总是优先于SQL Server提供的返回值。
Sp_Addmessage 这个存储过程允许开发者创建自定义错误信息。 SQL Server以相同的方式处理系统错误信息和自定义错误信息。所有信息存放在Sysmessages表中,这些错误信息也可以自动写到WmdowsNT应用程序事件日志中。 $$Error 这个全局变量含有最近执行的Transact-SQL语句的错误号,执行一条语句时这个变量被清除和重设。如果语句成功执行,返回值0。可以使用@@Error全局变量检测特定的错误号,或者有条件地退出存储