本节书摘来自异步社区出版社《锋利的SQL(第2版)》一书中的第1章,第1.5节,作者:张洪举 王晓文,更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.5 常量和变量
锋利的SQL(第2版)
常量和变量是程序设计过程中必不可少的元素,在前面的内容也涉及了对变量的简单介绍。
1.5.1 常量
常量,也称为文字值或标量值,是表示一个特定数据值的符号。常量的格式取决于它所表示的值的数据类型。
1.字符串常量
字符串常量包含在单引号内,可以由字母数字字符(a-z、A-Z和0-9)以及特殊字符(如!、@和#)组成。例如:
'这是我的字符串常量'
如果单引号中的字符串包含一个嵌入的引号,可以使用两个单引号表示嵌入的单引号。对于嵌入在双引号中的字符串则没有必要这样做。例如,下面是“I’m Tom”常量的正确书写方式。
'I''m Tom'
空字符串用中间没有任何字符的两个单引号表示。
2.Unicode字符串常量
Unicode字符串的格式与普通字符串相似,但它前面有一个N标识符(N代表SQL-92标准中的区域语言)。N前缀必须是大写字母。例如,'Michel'是字符串常量,而N'Michel'则是Unicode常量。
Unicode常量被解释为Unicode格式数据,并且不使用代码页进行计算。对于字符数据,存储Unicode数据时,每个字符使用2个字节,而不是每个字符1个字节。
3.二进制常量
二进制常量具有前辍0x,并且是十六进制数字字符串。这些常量不使用引号括起。例如,下面是二进制字符串的示例:
0xAE
0x12Ef
0x69048AEFDD010E
0x (空二进制常量)
4.bit常量
bit常量使用数字0或1表示,并且不括在引号中。如果使用一个大于1的数字,则该数字将转换为1。
5.datetime常量
datetime常量使用特定格式的字符日期值来表示,并被单引号括起来。SQL Server可识别下列格式中用单引号(')括起来的日期和时间。
字母日期,如'April 15, 1998'。
数值日期格式,如'4/15/1998'。
未分隔的字符串格式,如'19981207'指1998年12月7日。
下面分别是使用24和12小时制方式表示的时间常量:
'14:30:24'
'04:24 PM'
SQL Server所支持的所有时间格式,请参考1.7.4节的表1-16。
6.integer常量
integer常量以没有用引号括起来并且不包含小数点的数字字符串来表示。integer常量必须全部为数字,并且不能包含小数。例如:
1894
2
7.decimal常量
decimal常量由没有用引号括起来并且包含小数点的数字字符串来表示。例如:
1894.1204
2.0
8.float和real常量
float和real常量使用科学记数法来表示。例如:
101.5E5
0.5E-2
9.money常量
money常量是以可选的货币符号作为前缀为的一串数字。money常量可以包含小数点,但是不能使用引号括起来。例如:
$12
$542023.14
10.uniqueidentifier常量
uniqueidentifier常量是表示GUID的字符串。可以使用字符或二进制字符串格式指定。例如,下面的示例指定的是相同的GUID:
'6F9619FF-8B86-D011-B42D-00C04FC964FF'
0xff19966f868b11d0b42d00c04fc964ff
11.指定负数和正数
可以在数字前面添加“+”和“-”一元运算符来表示正数和负数。如果没有添加一元运算符,则默认为正数。例如:
-- integer表达式
-2147483648
-- decimal表达式
+145345234.2234
-2147483648.10
-- float表达式
-12E5
-- money表达式
-$45.56
1.5.2 变量
变量对应内存中的一个存储空间。与常量不同,变量的值在运行过程中可以随时改变。
1.局部变量和全局变量
根据变量的作用范围不同,可以分为局部变量和全局变量。
局部变量是用户在程序中定义的变量,它仅在定义的程序范围内有效。局部变量可以用来保存从表中读取的数据,也可以作为临时变量保存计算的中间结果。在批处理和脚本中的变量通常用于:
作为计数器计算循环执行的次数或控制循环执行的次数;
保存数据值以供控制流语句测试;
保存存储过程返回代码要返回的数据值或函数返回值。
局部变量名称的第一个字符必须为一个@。
在SQL Server的早期版本中,如果变量以@@开头,则被称为全局变量。这些变量实际上是SQL Server的系统函数,它们的语法遵循函数的规则。用户可以在程序中使用这些函数测试系统特性和SQL命令的执行情况。
2.声明变量
变量只有在声明后才能使用,可以使用DECLARE语句来声明变量。在声明变量时可以指定变量的数据类型和长度。例如,下面的DECLARE语句使用int数据类型创建名为@MyCounter的局部变量。
DECLARE @MyCounter int;
如果要声明多个局部变量,需要在定义的局部变量后使用一个逗号,然后指定下一个局部变量名称和数据类型。例如,下面的DECLARE语句创建三个局部变量,名称分别为@LastName、@FirstName和@Salary。
DECLARE @LastName nvarchar(30), @FirstName nvarchar(20), @Salary decimal(7,2);
在使用变量时,需要注意变量的作用域。变量具有局部作用域,只在定义它们的批处理或过程中可见。作用域范围从声明变量的地方开始到声明变量的批处理或存储过程的结尾。例如,下面的脚本存在语法错误,因为在一个批处理中引用了在另一个批处理中声明的变量。
USE AdventureWorks2014; -- 指定使用的数据库
GO
DECLARE @MyVariable int;
SET @MyVariable = 1;
GO -- 该语句将结束批
-- @MyVariable已经超出了范围并不再存在
-- 下面的SELECT语句会发生语法错误,因为它引用了一个不存在的变量
SELECT *
FROM HumanResources.Employee
WHERE EmployeeID = @MyVariable;
3.为变量设置值
在声明变量后,变量值被默认设置为NULL。要为变量赋值,可以使用SET或SELECT语句。其中,SET是为变量赋值的首选方法。
仍旧使用上面的示例,将声明的MyVariable变量赋值为1,并在SELECT语句的WHERE子句中使用该变量。语句如下:
USE AdventureWorks2014; -- 指定使用的数据库
GO
DECLARE @MyVariable int;
SET @MyVariable = 1; -- 设置变量值为1
SELECT * FROM HumanResources.Employee
WHERE EmployeeID = @MyVariable;
GO
变量也可以通过选择列表中当前所引用的值赋值。如果在选择列表中引用变量,则它应当被赋以标量值或者SELECT语句应仅返回一行。例如:
USE AdventureWorks2014; -- 指定使用的数据库
GO
DECLARE @EmpIDVariable int;
SELECT @EmpIDVariable = MAX(EmployeeID)
FROM HumanResources.Employee;
SELECT @EmpIDVariable; --显示@EmpIDVariable的值
GO
注意
如果在单个SELECT语句中有多个赋值子句,SQL Server并不保证表达式求值的顺序。只有当赋值之间有引用时才能看到影响。
如果SELECT语句返回多行而且变量引用一个非标量表达式,则变量被设置为结果集最后一行中表达式的返回值。例如,下面的语句将@EmpIDVariable设置为所返回的最后一行的EmployeeID字段的值。
USE AdventureWorks2014;
GO
DECLARE @EmpIDVariable int;
SELECT @EmpIDVariable = EmployeeID
FROM HumanResources.Employee
ORDER BY EmployeeID DESC;
SELECT @EmpIDVariable; --显示@EmpIDVariable的值
GO
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。