变量可以保存查询之后的结果,可以在查询语句中使用变量,也可以将变量中的值插入到数据表中,在Transact-SQL中变量的使用非常灵活方便,可以在任何Transact-SQL语句集合中声明使用,根据其生命周期,可以分为全局变量和局部变量。
全局变量是SQL Server系统中使用的变量,其作用范围并不仅仅局限于某一程序,而是任何程序均可以随时调用。全局变量通常存储一些SQL Server的配置设定值和统计数据。用户可以在程序中使用全局变量来测试系统的设定值或者是Transact-SQL命令执行后的状态值。在使用全局变量时应注意以下几点。
全局变量不是由用户的程序定义的,它们是在服务器级定义的。用户只能使用预先定义的全局变量,而不能修改全局变量。引用全局变量时,必须以标记符“@@”开头。
SQL Server 2019中常用的全局变量及其含义如下:
·@@CONNECTIONS:返回SQL Server自上次启动以来尝试的连接数,无论连接是成功还是失败。
·@@CPU_BUSY:返回SQL Server自上次启动后的工作时间。其结果以CPU时间增量或“滴答数”来表示,此值为CPU工作时间的累积值,因此,可能会超出实际占用CPU的时间。乘以@@TIMETICKS即可转换为微秒。
·@@CURSOR_ROWS:返回连接的数据库上打开的上一个游标中的当前限定行的数目。为了提高性能,SQL Server可异步填充大型键集和静态游标。可调用@@CURSOR_ROWS以确定当其被调用时检索了游标符合条件的行数。
·@@DATEFIRST:针对会话返回SET DATEFIRST的当前值。
·@@DBTS:返回当前数据库的当前timestamp数据类型的值。这一时间戳值在数据库中必须是唯一的。
·@@ERROR:返回执行的上一个Transact-SQL语句出现错误时对应的错误编号。
·@@FETCH_STATUS:返回针对连接的数据库当前打开的任何游标,发出的上一条游标FETCH语句的状态。
·@@IDENTITY:返回插入到数据表的IDENTITY列的最后一个值。
·@@IDLE:返回SQL Server自上次启动后的空闲时间。结果以CPU时间增量或“时钟周期”来表示,是所有的累积值,因此该值可能超过实际经过的时间。乘以@@TIMETICKS即可转换为微秒。
·@@IO_BUSY:返回自SQL Server最近一次启动以来,SQL Server已经用于执行输入和输出操作的时间。其结果是CPU时间增量(时钟周期),是CPU执行操作的累积值,这个值可能超过实际消逝的时间。乘以@@TIMETICKS即可转换为微秒。
·@@LANGID:返回当前使用的语言对应的本地语言标识符(ID)。
·@@LANGUAGE:返回当前所用语言的名称。
·@@LOCK_TIMEOUT:返回当前会话的锁定超时的设置值(单位为毫秒)。
·@@MAX_CONNECTIONS:返回SQL Server实例允许同时进行的最大用户连接数。返回的数值不一定是当前配置的数值。
·@@MAX_PRECISION:按照服务器中的当前设置,返回decimal和numeric数据类型所用的精度级别。默认情况下,最大精度级别38。
·@@NESTLEVEL:返回在本地服务器上执行的当前存储过程的嵌套级别(初始值为0)。
·@@OPTIONS:返回有关当前SET选项的信息。
·@@PACK_RECEIVED:返回SQL Server自上次启动后从网络读取的输入数据包数。
·@@PACK_SENT:返回SQL Server自上次启动后写入网络的输出数据包个数。
·@@PACKET_ERRORS:返回自上次启动SQL Server后,在SQL Server连接上发生的网络数据包错误数。
·@@ROWCOUNT:返回上一次语句影响的数据行的行数。
·@@PROCID:返回Transact-SQL当前模块的对象标识符(ID)。Transact-SQL模块可以是存储过程、用户定义函数或触发器。不能在CLR模块或进程内的数据访问接口中指定@@PROCID 。
·@@SERVERNAME:返回运行SQL Server的本地服务器的名称。
·@@SERVICENAME:返回SQL Server正在运行的注册表项的名称。若当前实例为默认实例,则@@SERVICENAME返回MSSQLSERVER;若当前实例是命名实例,则该函数返回该实例名。
·@@SPID:返回当前用户进程的会话ID。
·@@TEXTSIZE:返回SET语句的TEXTSIZE选项的当前值,它指定SELECT语句返回的text或image数据类型的最大长度,其单位为字节。
·@@TIMETICKS:返回每个时钟周期的微秒数。
·@@TOTAL_ERRORS:返回自上次启动SQL Server之后,SQL Server所遇到的磁盘写入错误数。
·@@TOTAL_READ:返回SQL Server自上次启动后,由SQL Server读取(非缓存读取)的磁盘的数目。
·@@TOTAL_WRITE:返回自上次启动SQL Server以来,SQL Server所执行的磁盘写入数。
·@@TRANCOUNT:返回当前连接的活动事务数。
·@@VERSION:返回当前安装的日期、版本和处理器类型。
【例4.1】查看当前SQL Server的版本信息和服务器名称,输入如下语句:
SELECT @@VERSION AS 'SQL Server版本', @@SERVERNAME AS '服务器名称'
使用Windows身份验证登录到SQL Server服务器之后,新建立一个对当前连接的数据库的查询,输入上面的语句,单击【执行】按钮,执行结果如图4-1所示。
图4-1 查看执行结果
局部变量是一个能够拥有特定数据类型的对象,它的作用范围仅限制在程序内部。在批处理和脚本中变量可以有如下用途:作为计数器计算循环执行的次数或控制循环执行的次数,保存数据值供控制流语句测试,以及保存由存储过程代码返回的数据值或者函数返回值。局部变量被引用时要在其名称前加上标志“@”,而且必须先用DECLARE命令声明后才可以使用。定义局部变量的语法形式如下:
DECLARE {@local-variable data-type} [...n]
@local-variable参数用于指定局部变量的名称,变量名必须以符号“@”开头,且必须符合SQL Server的命名规则。
data-type参数用于设置局部变量的数据类型及其大小。data-type可以是任何由系统提供的或用户定义的数据类型。但是,局部变量不能是text、ntext或image数据类型。
局部变量的名称不能与全局变量的名称相同,否则会在应用程序中出现不可预测的结果。
【例4.2】使用DECLARE语句创建int数据类型的名为@MyCounter的局部变量,输入如下语句:
DECLARE @MyCounter int;
若要声明多个局部变量,在定义的第一个局部变量后使用一个逗号,然后指定下一个局部变量名称和数据类型。
【例4.3】声明3个名为@Name、@Phone和@Address的局部变量,并将每个变量都初始化为NULL,输入如下语句:
DECLARE @Name varchar(30), @Phone varchar(20), @Address char(2);
使用DECLARE命令声明并创建局部变量之后,会将其初始值设为NULL,如果想要设置局部变量的值,必须使用SELECT命令或者SET命令。其语法形式为:
SET {@local-variable=expression} 或者SELECT {@local-variable=expression } [, ...n]
其中,@local-variable是给其赋值并声明的局部变量。expression是任何有效的SQL Server表达式。
【例4.4】使用SELECT语句为@MyCount变量赋值,最后输出@MyCount变量的值,输入如下语句:
DECLARE @MyCount INT SELECT @MyCount =100 SELECT @MyCount GO
执行结果如图4-2所示。
图4-2 执行后的结果
【例4.5】通过查询语句给变量赋值,输入如下语句:
DECLARE @rows int SET @rows=(SELECT COUNT(*) FROM Member) SELECT @rows GO
该语句查询出Member表中总的记录数,并将其保存在rows局部变量中。
【例4.6】在SELECT查询语句中,使用由SET赋值的局部变量,输入如下语句:
USE test GO DECLARE @memberType varchar(100) SET @memberType ='VIP' SELECT RTRIM(FirstName)+' '+RTRIM(LastName) AS Name, @memberType FROM member GO
批处理是同时从应用程序发送到SQL Server并得以执行的一组单条或多条的Transact-SQL语句。这些语句为了达到一个整体的目标而同时执行。GO命令表示批处理的结束。如果Transact-SQL脚本中没有GO命令,那么它将被作为单个批处理来执行。
SQL Server将批处理中的语句作为一个整体,编译为一个执行计划,批处理中的语句是一起提交给服务器的,所以可以节省系统开销。
批处理中的语句如果在编译时出现错误,则不能产生执行计划,那么批处理中的任何一个语句都不会执行。批处理运行时出现错误将有如下影响:
·大多数运行时错误将停止执行批处理中当前语句和它之后的语句。
·某些运行时错误(如违反约束)仅停止执行当前语句,而继续执行批处理中其他所有语句。
·在遇到运行时错误的语句之前执行的语句不受影响。唯一例外的情况是批处理位于事务中并且错误导致事务回滚。在这种情况下,所有在运行时错误之前执行的未提交数据修改都将回滚。
批处理使用时有如下限制规则:
·CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE RULE、CREATE SCHEMA、CREATE TRIGGER和CREATE VIEW语句不能在批处理中与其他语句组合使用。批处理必须以CREATE语句开始。所有跟在该批处理后的其他语句将被解释为第一个CREATE语句定义的一部分。
·不能在同一个批处理中更改表,然后引用新列。
·如果EXECUTE语句是批处理中的第一句,则不需要EXECUTE关键字。如果EXECUTE语句不是批处理中的第一条语句,则需要EXECUTE关键字。
脚本是存储在文件中的一系列Transact-SQL语句。Transact-SQL脚本包含一个或多个批处理。Transact-SQL脚本主要有以下用途:
·在服务器上保存用来创建和填充数据库的程序的永久副本,作为一种备份机制。
·必要时将语句从一台计算机传输到另一台计算机。
·通过让新员工发现代码中的问题、了解代码或更改代码从而快速对其进行培训。
脚本可以看作一个单元,以文本文件的形式存储在系统中,在脚本中可以使用系统函数和局部变量,例如一个脚本中包含了如下代码:
该脚本中使用了6条语句,分别包含了USE语句、局部变量的定义、CREATE语句、INSERT语句、SELECT语句以及SET赋值语句,所有的这些语句在一起完成了person数据表的创建、数据的插入并统计了插入的记录总数。
USE语句用来设置当前使用的数据库,可以看到,因为使用了USE语句,所以在执行INSERT和SELECT语句时,它们将在指定的数据库(test_db)中进行操作。