SQL Server系统函数
5.1 PIVOT和UNPIVOT
可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式更改为另一个表。PIVOT 通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合。UNPIVOT 与 PIVOT 执行相反的操作,将表值表达式的列转换为列值。
注意 |
对升级到 SQL Server 2005 或更高版本的数据库使用 PIVOT 和 UNPIVOT 时,必须将数据库的兼容级别设置为 90 或更高。有关如何设置数据库兼容级别的信息,请参阅 sp_dbcmptlevel (Transact-SQL)。 |
PIVOT 提供的语法比一系列复杂的 SELECT...CASE 语句中所指定的语法更简单和更具可读性。有关 PIVOT 语法的完整说明,请参阅 FROM (Transact-SQL)。
以下是带批注的 PIVOT 语法。
SELECT <非透视的列>,
[第一个透视的列] AS <列名称>,
[第二个透视的列] AS <列名称>,
...
[最后一个透视的列] AS <列名称>,
FROM
(<生成数据的 SELECT 查询>)
AS <源查询的别名>
PIVOT
(
<聚合函数>(<要聚合的列>)
FOR
[<包含要成为列标题的值的列>]
IN ( [第一个透视的列], [第二个透视的列],
... [最后一个透视的列])
) AS <透视表的别名>
<可选的 ORDER BY 子句>;
下面的代码示例生成一个两列四行的表。
USE AdventureWorks2008R2 ;
GO
SELECT DaysToManufacture, AVG(StandardCost) AS AverageCost
FROM Production.Product
GROUP BY DaysToManufacture;
下面是结果集:
DaysToManufacture AverageCost
0 5.0885
1 223.88
2 359.1082
4 949.4105
没有定义 DaysToManufacture 为 3 的产品。
以下代码显示相同的结果,该结果经过透视以使 DaysToManufacture 值成为列标题。提供一个列表示三 [3] 天,即使结果为 NULL。
-- Pivot table with one row and five columns
SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days,
[0], [1], [2], [3], [4]
FROM
(SELECT DaysToManufacture, StandardCost
FROM Production.Product) AS SourceTable
PIVOT
(
AVG(StandardCost)
FOR DaysToManufacture IN ([0], [1], [2], [3], [4])
) AS PivotTable;
下面是结果集:
Cost_Sorted_By_Production_Days 0 1 2 3 4
AverageCost 5.0885 223.88 359.1082 NULL 949.4105
可能会用到 PIVOT 的常见情况是:需要生成交叉表格报表以汇总数据。例如,假设需要在 AdventureWorks2008R2 示例数据库中查询 PurchaseOrderHeader 表以确定由某些特定雇员所下的采购订单数。以下查询提供了此报表(按供应商排序)。
USE AdventureWorks2008R2;
GO
SELECT VendorID, [250] AS Emp1, [251] AS Emp2, [256] AS Emp3, [257] AS Emp4, [260] AS Emp5
FROM
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [250], [251], [256], [257], [260] )
) AS pvt
ORDER BY pvt.VendorID;
以下为部分结果集。
VendorID Emp1 Emp2 Emp3 Emp4 Emp5
1492 2 5 4 4 4
1494 2 5 4 5 4
1496 2 4 4 5 5
1498 2 5 4 4 4
1500 3 4 4 5 4
将在 EmployeeID 列上透视此嵌套 select 语句返回的结果。
SELECT PurchaseOrderID, EmployeeID, VendorID
FROM PurchaseOrderHeader;
这意味着 EmployeeID 列返回的唯一值自行变成了最终结果集中的字段。因此,在透视子句中指定的每个 EmployeeID 号都有相应的一列:在本例中为雇员 164、198、223、231 和 233。PurchaseOrderID 列作为值列,将根据此列对最终输出中返回的列(称为分组列)进行分组。在本例中,通过 COUNT 函数聚合分组列。请注意,将显示一条警告消息,指出为每个雇员计算 COUNT 时未考虑显示在 PurchaseOrderID 列中的任何空值。
重要提示 |
如果聚合函数与 PIVOT 一起使用,则计算聚合时将不考虑出现在值列中的任何空值。 |
UNPIVOT 将与 PIVOT 执行几乎完全相反的操作,将列转换为行。假设以上示例中生成的表在数据库中存储为 pvt,并且您需要将列标识符 Emp1、Emp2、Emp3、Emp4 和 Emp5 旋转为对应于特定供应商的行值。这意味着必须标识另外两个列。包含要旋转的列值(Emp1、Emp2...)的列将被称为 Employee,将保存当前位于待旋转列下的值的列被称为 Orders。这些列分别对应于 Transact-SQL 定义中的 pivot_column 和value_column。以下为该查询。
--Create the table and insert values as portrayed in the previous example.
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int,
Emp3 int, Emp4 int, Emp5 int);
GO
INSERT INTO pvt VALUES (1,4,3,5,4,4);
INSERT INTO pvt VALUES (2,4,1,5,5,5);
INSERT INTO pvt VALUES (3,4,3,5,4,4);
INSERT INTO pvt VALUES (4,4,2,5,5,4);
INSERT INTO pvt VALUES (5,5,1,5,5,5);
GO
--Unpivot the table.
SELECT VendorID, Employee, Orders
FROM
(SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
FROM pvt) p
UNPIVOT
(Orders FOR Employee IN
(Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt;
GO
以下为部分结果集。
VendorID Employee Orders
---------- ---------- ------
1 Emp1 4
1 Emp2 3
1 Emp3 5
1 Emp4 4
1 Emp5 4
2 Emp1 4
2 Emp2 1
2 Emp3 5
2 Emp4 5
2 Emp5 5
...
请注意,UNPIVOT 并不完全是 PIVOT 的逆操作。PIVOT 会执行一次聚合,从而将多个可能的行合并为输出中的单个行。而 UNPIVOT 不会重现原始表值表达式的结果,因为行已经被合并了。另外,UNPIVOT 的输入中的空值不会显示在输出中,而在执行 PIVOT 操作之前,输入中可能有原始的空值。
AdventureWorks2008R2 示例数据库中的 Sales.vSalesPersonSalesByFiscalYears 视图将使用 PIVOT 返回每个销售人员在每个会计年度的总销售额。若要在 SQL Server Management Studio 中编写视图脚本,请在“对象资源管理器”中,在“视图”文件夹下找到 AdventureWorks2008R2 数据库对应的视图。右键单击该视图名称,再选择“编写视图脚本为”。
5.2 CONVERT与CAST
语法
Syntax for CAST:
CAST ( expression AS data_type [ ( length ) ] )
Syntax for CONVERT:
CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
参数
expression
任何有效的表达式。
data_type
目标数据类型。这包括xml、bigint 和sql_variant。不能使用别名数据类型。
length
指定目标数据类型长度的可选整数。默认值为30。
style
指定CONVERT 函数如何转换expression 的整数表达式。如果style为NULL,则返回NULL。该范围是由data_type 确定的。
CONVERT() 函数是把日期转换为新数据类型的通用函数。
CONVERT() 函数可以用不同的格式显示日期/时间数据。
语法
CONVERT(data_type(length),data_to_be_converted,style)
data_type(length) 规定目标数据类型(带有可选的长度)。data_to_be_converted 含有需要转换的值。style 规定日期/时间的输出格式。
可以使用的 style 值:
Style ID |
Style 格式 |
100 或者 0 |
mon dd yyyy hh:miAM (或者 PM) |
101 |
mm/dd/yy |
102 |
yy.mm.dd |
103 |
dd/mm/yy |
104 |
dd.mm.yy |
105 |
dd-mm-yy |
106 |
dd mon yy |
107 |
Mon dd, yy |
108 |
hh:mm:ss |
109 或者 9 |
mon dd yyyy hh:mi:ss:mmmAM(或者 PM) |
110 |
mm-dd-yyyy |
111 |
yyyy/mm/dd |
112 |
yyyymmdd |
113 或者 13 |
dd mon yyyy hh:mm:ss:mmm(24h) |
114 |
hh:mi:ss:mmm(24h) |
120 或者 20 |
yyyy-mm-dd hh:mi:ss(24h) |
121 或者 21 |
yyyy-mm-dd hh:mi:ss.mmm(24h) |
126 |
yyyy-mm-ddThh:mm:ss.mmm(没有空格) |
130 |
dd mon yyyy hh:mi:ss:mmmAM |
131 |
dd/mm/yy hh:mi:ss:mmmAM |
实例
下面的脚本使用 CONVERT() 函数来显示不同的格式。我们将使用 GETDATE() 函数来获得当前的日期/时间:
CONVERT(VARCHAR(19),GETDATE())
CONVERT(VARCHAR(10),GETDATE(),110)
CONVERT(VARCHAR(11),GETDATE(),106)
CONVERT(VARCHAR(24),GETDATE(),113)
结果类似:
Dec 29 2008 11:45 PM
12-29-2008
29 Dec 08
29 Dec 2008 16:25:46.635
语句及查询结果:
SELECT CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM
SELECT CONVERT(varchar(100), GETDATE(), 1): 05/16/06
SELECT CONVERT(varchar(100), GETDATE(), 2): 06.05.16
SELECT CONVERT(varchar(100), GETDATE(), 3): 16/05/06
SELECT CONVERT(varchar(100), GETDATE(), 4): 16.05.06
SELECT CONVERT(varchar(100), GETDATE(), 5): 16-05-06
SELECT CONVERT(varchar(100), GETDATE(), 6): 16 05 06
SELECT CONVERT(varchar(100), GETDATE(), 7): 05 16, 06
SELECT CONVERT(varchar(100), GETDATE(), 8): 10:57:46
SELECT CONVERT(varchar(100), GETDATE(), 9): 05 16 2006 10:57:46:827AM
SELECT CONVERT(varchar(100), GETDATE(), 10): 05-16-06
SELECT CONVERT(varchar(100), GETDATE(), 11): 06/05/16
SELECT CONVERT(varchar(100), GETDATE(), 12): 060516
SELECT CONVERT(varchar(100), GETDATE(), 13): 16 05 2006 10:57:46:937
SELECT CONVERT(varchar(100), GETDATE(), 14): 10:57:46:967
SELECT CONVERT(varchar(100), GETDATE(), 20): 2006-05-16 10:57:47
SELECT CONVERT(varchar(100), GETDATE(), 21): 2006-05-16 10:57:47.157
SELECT CONVERT(varchar(100), GETDATE(), 22): 05/16/06 10:57:47 AM
SELECT CONVERT(varchar(100), GETDATE(), 23): 2006-05-16
SELECT CONVERT(varchar(100), GETDATE(), 24): 10:57:47
SELECT CONVERT(varchar(100), GETDATE(), 25): 2006-05-16 10:57:47.250
SELECT CONVERT(varchar(100), GETDATE(), 100): 05 16 2006 10:57AM
SELECT CONVERT(varchar(100), GETDATE(), 101): 05/16/2006
SELECT CONVERT(varchar(100), GETDATE(), 102): 2006.05.16
SELECT CONVERT(varchar(100), GETDATE(), 103): 16/05/2006
SELECT CONVERT(varchar(100), GETDATE(), 104): 16.05.2006
SELECT CONVERT(varchar(100), GETDATE(), 105): 16-05-2006
SELECT CONVERT(varchar(100), GETDATE(), 106): 16 05 2006
SELECT CONVERT(varchar(100), GETDATE(), 107): 05 16, 2006
SELECT CONVERT(varchar(100), GETDATE(), 108): 10:57:49
SELECT CONVERT(varchar(100), GETDATE(), 109): 05 16 2006 10:57:49:437AM
SELECT CONVERT(varchar(100), GETDATE(), 110): 05-16-2006
SELECT CONVERT(varchar(100), GETDATE(), 111): 2006/05/16
SELECT CONVERT(varchar(100), GETDATE(), 112): 20060516
SELECT CONVERT(varchar(100), GETDATE(), 113): 16 05 2006 10:57:49:513
SELECT CONVERT(varchar(100), GETDATE(), 114): 10:57:49:547
SELECT CONVERT(varchar(100), GETDATE(), 120): 2006-05-16 10:57:49
5.3 DATEADD
将指定 number 时间间隔(有符号整数)与指定 date 的指定 datepart 相加后,返回该 date。
DATEADD (datepart , number , date )
datepart
是与 integernumber 相加的 date 部分。 下表列出了所有有效的 datepart 参数。 用户定义的变量等效项无效。
datepart |
缩写形式 |
year |
yy ,yyyy |
quarter |
qq ,q |
month |
mm ,m |
dayofyear |
dy ,y |
day |
dd ,d |
week |
wk ,ww |
weekday |
dw ,w |
hour |
hh |
minute |
mi ,n |
second |
ss ,s |
millisecond |
ms |
microsecond |
mcs |
nanosecond |
ns |
number
一个表达式,它可以解析为与 date 的 datepart 相加的 int。 用户定义的变量是有效的。
如果您指定一个带小数的值,则将小数截去且不进行舍入。
date
是一个可以解析为 time、date、smalldatetime、datetime、datetime2 或 datetimeoffset 值的表达式。 date 可以是表达式、列表达式、用户定义的变量或字符串文字。 如果表达式是字符串文字,则它必须解析为一个 datetime 值。 为避免不确定性,请使用四位数年份。 有关两位数年份的信息,请参阅 配置两位数年份截止服务器配置选项。
返回数据类型为 date 参数的数据类型,字符串文字除外。
字符串文字的返回数据类型为 datetime。 如果字符串文字的秒数小数位数超过三位 (.nnn) 或包含时区偏移量部分, 将引发错误。
dayofyear 、day 和 weekday 返回相同的值。
每个 datepart 及其缩写都返回相同的值。
如果 datepart 为 month 且 date 月份比返回月份的天数多,因而 date 中的日在返回月份中不存在,则返回返回月份的最后一天。 例如,9 月份有 30 天;因此,下面两个语句返回 2006-09-30 00:00:00.000:
SELECT DATEADD(month, 1, '2006-08-30');
SELECT DATEADD(month, 1, '2006-08-31');
5.4 DATEDIFF
返回指定的 startdate 和 enddate 之间所跨的指定 datepart 边界的计数(带符号的整数)。
DATEDIFF ( datepart , startdate , enddate )
5.5 CEILING
返回大于或等于指定数值表达式的最小整数。
语法
CEILING ( numeric_expression )
参数
numeric_expression
是精确数字或近似数字数据类型类别(bit 数据类型除外)的表达式。
返回类型
返回与numeric_expression 相同的类型。
示例
以下示例显示使用CEILING 函数的正数、负数和零值。
SELECT CEILING($123.45), CEILING($-123.45), CEILING($0.0)
GO
下面是结果集:
--------- --------- -------------------------
124.00 -123.00 0.00
5.6 FLOOR
返回小于或等于指定数值表达式的最大整数。
语法
FLOOR ( numeric_expression )
参数
numeric_expression
精确数字或近似数字数据类型类别(bit 数据类型除外)的表达式。
返回类型
返回与numeric_expression 相同的类型。
示例
以下示例显示正数、负数和货币值在FLOOR 函数中的运用。
SELECT FLOOR(123.45), FLOOR(-123.45), FLOOR($123.45)
--------- --------- -----------
123 -124 123.0000
5.7 LTRIM
返回删除了前导空格之后的字符表达式。
语法
LTRIM ( character_expression )
参数
character_expression
字符或二进制数据的表达式。character_expression 可以是常量、变量或列。character_expression 必须属于某个可隐式转换为varchar 的数据类型(text、ntext 和image 除外)。否则,请使用CAST 显式转换character_expression。
返回类型
varchar 或nvarchar
示例
以下示例使用LTRIM 删除字符变量中的前导空格。
DECLARE @string_to_trim varchar(60);
SET @string_to_trim = ' Five spaces are at the beginning of this
string.';
SELECT 'Here is the string without the leading spaces: ' +
LTRIM(@string_to_trim);
GO
下面是结果集:
------------------------------------------------------------------------
Here is the string without the leading spaces: Five spaces are at the beginning of this string.
(1 row(s) affected)
5.8 PARTITION FUNCTION
在当前数据库中创建一个函数,该函数可根据指定列的值将表或索引的各行映射到分区。使用CREATE PARTITION FUNCTION 是创建已分区表或索引的第一步。在SQL Server 2012 中,一张表或一个索引最多可以有15,000 个分区。
语法
CREATE PARTITION FUNCTION partition_function_name ( input_parameter_type )
AS RANGE [ LEFT | RIGHT ]
FOR VALUES ( [ boundary_value [ ,...n ] ] )
[ ; ]
参数
partition_function_name
是分区函数的名称。分区函数名称在数据库内必须唯一,并且符合标识符的规则。
input_parameter_type
是用于分区的列的数据类型。当用作分区列时,除text、ntext、image、xml、timestamp、varchar(max)、nvarchar(max)、varbinary(max)、别名数据类型或CLR 用户定义数据类型外,所有数据类型均有效。
实际列(也称为分区列)是在CREATE TABLE 或CREATE INDEX 语句中指定的。
boundary_value
为使用partition_function_name 的已分区表或索引的每个分区指定边界值。如果boundary_value 为空,则分区函数使用partition_function_name 将整个表或索引映射到单个分区。只能使用CREATE TABLE 或CREATE INDEX 语句中指定的一个分区列。
boundary_value 是可以引用变量的常量表达式。这包括用户定义类型变量,或函数以及用户定义函数。它不能引用Transact-SQL 表达式。boundary_value 必须与input_parameter_type 中提供的数据类型相匹配或者可隐式转换为该数据类型,并且如果该值的大小和小数位数与input_parameter_type 中相应的值的大小和小数位数不匹配,则在隐式转换过程中该值不能被截断。
注意注意
如果boundary_value 包含datetime 或smalldatetime 文字值,则为这些文字值在计算时假设us_english 是会话语言。不推荐使用此行为。要确保分区函数定义对于所有会话语言都具有预期的行为,建议使用对于所有语言设置都以相同方式进行解释的常量,例如yyyymmdd 格式;或者将文字值显式转换为特定样式。若要确定服务器的语言会话,请运行SELECT @@LANGUAGE。
...n
指定boundary_value 提供的值的数目,不能超过14,999。创建的分区数等于n + 1。不必按顺序列出各值。如果值未按顺序列出,则数据库引擎将对它们进行排序、创建函数并返回一个警告,说明未按顺序提供值。如果n 包括任何重复的值,则数据库引擎将返回错误。
LEFT | RIGHT
指定当间隔值由数据库引擎按升序从左到右排序时,boundary_value [ ,...n ] 属于每个边界值间隔的哪一侧(左侧还是右侧)。如果未指定,则默认值为LEFT。
注释
分区函数的作用域被限制为在其中创建该分区函数的数据库。在该数据库内,分区函数驻留在与其他函数的命名空间不同的一个单独命名空间内。
分区列为空值的所有行都放在最左侧分区中,除非将NULL 指定为边界值并指定了RIGHT。在这种情况下,最左侧分区为空分区,NULL 值被放置在后面的分区中。
权限
可以使用下列任何一种权限执行CREATE PARTITION FUNCTION:
ALTER ANY DATASPACE 权限。默认情况下,此权限授予sysadmin 固定服务器角色和db_owner 及db_ddladmin 固定数据库角色的成员。
在其中创建分区函数的数据库的CONTROL 或ALTER 权限。
在其中创建分区函数的数据库所在服务器的CONTROL SERVER 或ALTER ANY DATABASE 权限。
示例
A.对int 列创建RANGE LEFT 分区函数
以下分区函数将表或索引分为四个分区。
Transact-SQL
CREATE PARTITION FUNCTION myRangePF1 (int)
AS RANGE LEFT FOR VALUES (1, 100, 1000);
下表显示对分区依据列col1 使用此分区函数的表如何进行分区。
分区
1
2
3
4
值
col1 <= 1
col1 > 1 AND col1 <= 100
col1 > 100 AND col1 <=1000
col1 > 1000
B.对int 列创建RANGE RIGHT 分区函数
以下分区函数与上一个示例使用相同的boundary_value [ ,...n ] 值,但它指定RANGE RIGHT。
Transact-SQL
CREATE PARTITION FUNCTION myRangePF2 (int)
AS RANGE RIGHT FOR VALUES (1, 100, 1000);
下表显示对分区依据列col1 使用此分区函数的表如何进行分区。
分区
1
2
3
4
值
col1 < 1
col1 >= 1 AND col1 < 100
col1 >= 100 AND col1 < 1000
col1 >= 1000
C.对datetime 列创建RANGE RIGHT 分区函数
以下分区函数将表或索引分成12 个分区,每个分区对应datetime 列中的一年中一个月的值。
Transact-SQL
CREATE PARTITION FUNCTION [myDateRangePF1] (datetime)
AS RANGE RIGHT FOR VALUES ('20030201', '20030301', '20030401',
'20030501', '20030601', '20030701', '20030801',
'20030901', '20031001', '20031101', '20031201');
下表显示对分区依据列datecol 使用此分区函数的表或索引如何进行分区。
分区
1
2
...
11
12
值
datecol < February 1, 2003
datecol >= February 1, 2003 AND datecol < March 1, 2003
datecol >= November 1, 2003 AND col1 < December 1, 2003
col1 >= December 1, 2003
D.对char 列创建分区函数
以下分区函数将表或索引分为四个分区。
Transact-SQL
CREATE PARTITION FUNCTION myRangePF3 (char(20))
AS RANGE RIGHT FOR VALUES ('EX', 'RXE', 'XR');
下表显示对分区依据列col1 使用此分区函数的表如何进行分区。
分区
1
2
3
4
值
col1 < EX...
col1 >= EX AND col1 < RXE...
col1 >= RXE AND col1 < XR...
col1 >= XR
E.创建15,000 个分区
以下分区函数将表或索引分为15,000 个分区。
Transact-SQL
--Create integer partition function for 15,000 partitions.
DECLARE @IntegerPartitionFunction nvarchar(max) = N'CREATE PARTITION FUNCTION IntegerPartitionFunction (int) AS RANGE RIGHT FOR VALUES (';
DECLARE @i int = 1;
WHILE @i < 14999
BEGIN
SET @IntegerPartitionFunction += CAST(@i as nvarchar(10)) + N', ';
SET @i += 1;
END
SET @IntegerPartitionFunction += CAST(@i as nvarchar(10)) + N');';
EXEC sp_executesql @IntegerPartitionFunction;
GO
F.为多个年度创建分区
以下分区函数将表或索引在datetime2 列上分为50 个分区。对于2007 年1 月至2011 年1 月之间的每个月,都有一个分区。
Transact-SQL
--Create date partition function with increment by month.
DECLARE @DatePartitionFunction NVARCHAR(MAX)
SET @DatePartitionFunction=N'CREATE PARTITION FUNCTION DatePartitionFunction (datetime) AS RANGE LEFT FOR VALUES ('
DECLARE @i datetime
SET @i='2007-01-01'
WHILE @i<'2011-01-01'
BEGIN
SET @DatePartitionFunction=@DatePartitionFunction+''''+CONVERT(NVARCHAR(10),@i,120)+''''+N','
SET @i=DATEADD(mm,1,CONVERT(NVARCHAR(10),@i,120))
END
SET @DatePartitionFunction=@DatePartitionFunction+''''+CONVERT(NVARCHAR(10),@i,111)+''''+N');'
EXEC sp_executesql @DatePartitionFunction
GO
5.9 INDEX_COL
返回索引列名称。对于 XML 索引,返回 NULL。
INDEX_COL ( '[ database_name . [ schema_name ] .| schema_name ]
table_or_view_name', index_id , key_id )
database_name
数据库的名称。
schema_name
该索引所属架构的名称。
table_or_view_name
表或索引视图的名称。table_or_view_name 必须使用单引号分隔,并且可由数据库名称和架构名称完全限定。
index_id
索引的 ID。index_ID 的数据类型为 int。
key_id
索引键列的位置。key_ID 的数据类型为 int。
A. 使用 INDEX_COL 返回一个索引列名
以下示例返回索引 PK_SalesOrderDetail_SalesOrderID_LineNumber 中两个键列的列名。复制
USE AdventureWorks2008R2;
GO
SELECT
INDEX_COL (N'AdventureWorks2008R2.Sales.SalesOrderDetail', 1,1) AS
[Index Column 1],
INDEX_COL (N'AdventureWorks2008R2.Sales.SalesOrderDetail', 1,2) AS
[Index Column 2]
;
GO
下面是结果集:
Index Column 1 Index Column 2
-----------------------------------------------
SalesOrderID SalesOrderDetailID
5.10 char
1 2 3 |
制表符 CHAR(9) 换行符 CHAR(10) 回车 CHAR(13) |
Tab键 chr(9)
换行符chr(10)
回车符chr(13)
空格符chr(32)
print 'a' +char( 9 )+'b';
a b
print 'a' +char( 13 )+ 'b';
a
B
5.11 SCHEMA_ID
返回与架构名称关联的架构 ID。
适用范围:SQL Server(SQL Server 2008 至当前版本),Windows Azure SQL Database(初始版本至当前版本)。 |
SCHEMA_ID ( [ schema_name ] )
项 |
定义 |
schema_name |
架构的名称。 schema_name 的数据类型为 sysname。 如果未指定 schema_name,则 SCHEMA_ID 将返回调用方的默认架构的 ID。 |
int
如果 schema_name 不是有效架构,将返回 NULL。
SCHEMA_ID 将返回系统架构的 ID 和用户定义架构的 ID。 SCHEMA_ID 可以在选择列表、WHERE 子句和任何允许使用表达式的地方调用。
A.返回调用方的默认架构 ID
SELECT SCHEMA_ID();
GO
B.返回命名架构的架构 ID
USE AdventureWorks2012;
GO
SELECT SCHEMA_ID('HumanResources');
GO
5.12 OBJECTPROPERTY
返回当前数据库中架构范围内的对象的有关信息。 有关架构范围内对象的列表,请参阅 sys.objects (Transact-SQL)。 不能将此函数用于不属于架构范围内的对象,如数据定义语言 (DDL) 触发器和事件通知。
适用范围:SQL Server(SQL Server 2008 至当前版本),Windows Azure SQL Database(初始版本至当前版本)。 |
OBJECTPROPERTY ( id , property )
id
是表示当前数据库中对象 ID 的表达式。 id 的数据类型为 int,并假定为当前数据库上下文中的架构范围内的对象。
property
一个表达式,表示要为 id 指定的对象返回的信息。 property 可以是下列值之一。
注意 |
|||||||
除非另外注明,否则出现以下情况时,将返回 NULL:property 不是有效的属性名称,id 不是有效的对象 ID,id 不是指定的 property 支持的对象类型,或者调用方无权查看对象元数据。 |
|||||||
属性名称 |
对象类型 |
说明和返回的值 |
|||||
CnstIsClustKey |
约束 |
具有聚集索引的 PRIMARY KEY 约束。 1 = True 0 = False |
|||||
CnstIsColumn |
约束 |
单个列上的 CHECK、DEFAULT 或 FOREIGN KEY 约束。 1 = True 0 = False |
|||||
CnstIsDeleteCascade |
约束 |
具有 ON DELETE CASCADE 选项的 FOREIGN KEY 约束。 1 = True 0 = False |
|||||
CnstIsDisabled |
约束 |
禁用的约束。 1 = True 0 = False |
|||||
CnstIsNonclustKey |
约束 |
具有非聚集索引的 PRIMARY KEY 或 UNIQUE 约束。 1 = True 0 = False |
|||||
CnstIsNotRepl |
约束 |
使用 NOT FOR REPLICATION 关键字定义的约束。 1 = True 0 = False |
|||||
CnstIsNotTrusted |
约束 |
启用约束时未检查现有行,因此可能不是所有行都适用该约束。 1 = True 0 = False |
|||||
CnstIsUpdateCascade |
约束 |
具有 ON UPDATE CASCADE 选项的 FOREIGN KEY 约束。 1 = True 0 = False |
|||||
ExecIsAfterTrigger |
Trigger |
AFTER 触发器。 1 = True 0 = False |
|||||
ExecIsAnsiNullsOn |
Transact-SQL 函数、Transact-SQL 过程、Transact-SQL 触发器、视图 |
创建时的 ANSI_NULLS 设置。 1 = True 0 = False |
|||||
ExecIsDeleteTrigger |
Trigger |
DELETE 触发器。 1 = True 0 = False |
|||||
ExecIsFirstDeleteTrigger |
Trigger |
对表执行 DELETE 时触发的第一个触发器。 1 = True 0 = False |
|||||
ExecIsFirstInsertTrigger |
Trigger |
对表执行 INSERT 时触发的第一个触发器。 1 = True 0 = False |
|||||
ExecIsFirstUpdateTrigger |
Trigger |
对表执行 UPDATE 时触发的第一个触发器。 1 = True 0 = False |
|||||
ExecIsInsertTrigger |
Trigger |
INSERT 触发器。 1 = True 0 = False |
|||||
ExecIsInsteadOfTrigger |
Trigger |
INSTEAD OF 触发器。 1 = True 0 = False |
|||||
ExecIsLastDeleteTrigger |
Trigger |
对表执行 DELETE 时激发的最后一个触发器。 1 = True 0 = False |
|||||
ExecIsLastInsertTrigger |
Trigger |
对表执行 INSERT 时触发的最后一个触发器。 1 = True 0 = False |
|||||
ExecIsLastUpdateTrigger |
Trigger |
对表执行 UPDATE 时触发的最后一个触发器。 1 = True 0 = False |
|||||
ExecIsQuotedIdentOn |
Transact-SQL 函数、Transact-SQL 过程、Transact-SQL 触发器、视图 |
创建时的 QUOTED_IDENTIFIER 设置。 1 = True 0 = False |
|||||
ExecIsStartup |
过程 |
启动过程。 1 = True 0 = False |
|||||
ExecIsTriggerDisabled |
Trigger |
禁用的触发器。 1 = True 0 = False |
|||||
ExecIsTriggerNotForRepl |
Trigger |
定义为 NOT FOR REPLICATION 的触发器。 1 = True 0 = False |
|||||
ExecIsUpdateTrigger |
Trigger |
UPDATE 触发器。 1 = True 0 = False |
|||||
HasAfterTrigger |
表、视图 |
表或视图具有 AFTER 触发器。 1 = True 0 = False |
|||||
HasDeleteTrigger |
表、视图 |
表或视图具有 DELETE 触发器。 1 = True 0 = False |
|||||
HasInsertTrigger |
表、视图 |
表或视图具有 INSERT 触发器。 1 = True 0 = False |
|||||
HasInsteadOfTrigger |
表、视图 |
表或视图具有 INSTEAD OF 触发器。 1 = True 0 = False |
|||||
HasUpdateTrigger |
表、视图 |
表或视图具有 UPDATE 触发器。 1 = True 0 = False |
|||||
IsAnsiNullsOn |
Transact-SQL 函数、Transact-SQL 过程、表、Transact-SQL 触发器、视图 |
指定表的 ANSI NULLS 选项设置为 ON。 这表示所有对空值的比较都取值为 UNKNOWN。 只要表存在,此设置将应用于表定义中的所有表达式,包括计算列和约束。 1 = True 0 = False |
|||||
IsCheckCnst |
架构范围内的任何对象 |
CHECK 约束。 1 = True 0 = False |
|||||
IsConstraint |
架构范围内的任何对象 |
列或表的单列 CHECK、DEFAULT 或 FOREIGN KEY 约束。 1 = True 0 = False |
|||||
IsDefault |
架构范围内的任何对象 |
绑定的默认值。 1 = True 0 = False
|
|||||
IsDefaultCnst |
架构范围内的任何对象 |
DEFAULT 约束。 1 = True 0 = False |
|||||
IsDeterministic |
函数、视图 |
函数或视图的确定性属性。 1 = 确定 0 = 不确定 |
|||||
IsEncrypted |
Transact-SQL 函数、Transact-SQL 过程、表、Transact-SQL 触发器、视图 |
指示模块语句的原始文本已转换为模糊格式。 模糊代码的输出在 SQL Server 2005 的任何目录视图中都不能直接显示。对系统表或数据库文件没有访问权限的用户不能检索模糊文本。 但是,能沟通过 DAC 端口访问系统表的用户或能够直接访问数据库文件的用户可以使用此文本。 此外,能够向服务器进程附加调试器的用户可在运行时从内存中检索原始过程。 1 = 已加密 0 = 未加密 基本数据类型:int |
|||||
IsExecuted |
架构范围内的任何对象 |
可执行对象(视图、过程、函数或触发器)。 1 = True 0 = False |
|||||
IsExtendedProc |
架构范围内的任何对象 |
扩展过程。 1 = True 0 = False |
|||||
IsForeignKey |
架构范围内的任何对象 |
FOREIGN KEY 约束。 1 = True 0 = False |
|||||
IsIndexed |
表、视图 |
包含索引的表或视图。 1 = True 0 = False |
|||||
IsIndexable |
表、视图 |
可以创建索引的表或视图。 1 = True 0 = False |
|||||
IsInlineFunction |
函数 |
内联函数。 1 = 内联函数 0 = 非内联函数 |
|||||
IsMSShipped |
架构范围内的任何对象 |
安装 SQL Server 过程中创建的对象。 1 = True 0 = False |
|||||
IsPrimaryKey |
架构范围内的任何对象 |
PRIMARY KEY 约束。 1 = True 0 = False NULL = 非函数,或对象 ID 无效。 |
|||||
IsProcedure |
架构范围内的任何对象 |
过程。 1 = True 0 = False |
|||||
IsQuotedIdentOn |
Transact-SQL 函数、Transact-SQL 过程、表、Transact-SQL 触发器、视图、CHECK 约束、DEFAULT 定义 |
指定对象的引号标识符设置为 ON。 这表示用英文双引号分隔对象定义中涉及的所有表达式中的标识符。 1 = ON 0 = OFF |
|||||
IsQueue |
架构范围内的任何对象 |
Service Broker 队列 1 = True 0 = False |
|||||
IsReplProc |
架构范围内的任何对象 |
复制过程。 1 = True 0 = False |
|||||
IsRule |
架构范围内的任何对象 |
绑定规则。 1 = True 0 = False |
|||||
IsScalarFunction |
函数 |
标量值函数。 1 = 标量值函数 0 = 非标量值函数 |
|||||
IsSchemaBound |
函数、视图 |
使用 SCHEMABINDING 创建的绑定到架构的函数或视图。 1 = 绑定到架构 0 = 不绑定到架构。 |
|||||
IsSystemTable |
表 |
系统表。 1 = True 0 = False |
|||||
IsTable |
表 |
表。 1 = True 0 = False |
|||||
IsTableFunction |
函数 |
表值函数。 1 = 表值函数 0 = 非表值函数 |
|||||
IsTrigger |
架构范围内的任何对象 |
触发器。 1 = True 0 = False |
|||||
IsUniqueCnst |
架构范围内的任何对象 |
UNIQUE 约束。 1 = True 0 = False |
|||||
IsUserTable |
表 |
用户定义的表。 1 = True 0 = False |
|||||
IsView |
View |
视图。 1 = True 0 = False |
|||||
OwnerId |
架构范围内的任何对象 |
对象的所有者。
Nonnull = 对象所有者的数据库用户 ID。 |
|||||
TableDeleteTrigger |
表 |
表具有 DELETE 触发器。 >1 = 指定类型的第一个触发器的 ID。 |
|||||
TableDeleteTriggerCount |
表 |
表具有指定数目的 DELETE 触发器。 >0 = DELETE 触发器数目。 |
|||||
TableFullTextMergeStatus |
表 |
表所具有的全文索引当前是否正在合并。 0 = 表没有全文索引,或者全文索引未在合并。 1 = 全文索引正在合并。
|
|||||
TableFullTextBackgroundUpdateIndexOn |
表 |
表已启用全文后台更新索引(自动更改跟踪)。 1 = TRUE 0 = FALSE
|
|||||
TableFulltextCatalogId |
表 |
表的全文索引数据所在的全文目录的 ID。 非零 = 全文目录 ID,它与全文索引表中标识行的唯一索引相关。 0 = 表没有全文索引。
|
|||||
TableFulltextChangeTrackingOn |
表 |
表已启用全文更改跟踪。 1 = TRUE 0 = FALSE
|
|||||
TableFulltextDocsProcessed |
表 |
自开始全文索引以来所处理的行数。 在为进行全文搜索而正在编制索引的表中,将一个行的所有列视为要编制索引的文档的一部分。 0 = 没有完成的活动爬网或全文索引。 > 0 = 以下选项之一: 自从开始完整、增量或手动更改跟踪填充以来,由插入或更新操作处理的文档数。 自从执行以下操作以来由插入或更新操作处理的行数:启用具有后台更新索引填充功能的更改跟踪、更改全文索引架构、重建全文目录或重新启动 SQL Server 的实例等。 NULL = 表没有全文索引。
|
|||||
TableFulltextFailCount |
表 |
全文搜索未编制索引的行数。 0 = 填充已完成。 > 0 = 以下选项之一: 自从开始完整、增量和手动更新更改跟踪填充以来未编制索引的文档数。 对于具有后台更新索引功能的更改跟踪,则为自从开始填充或重新启动填充以来未编制索引的行数。 这可能由架构更改、目录重建、服务器重新启动等引起。 NULL = 表没有全文索引。
|
|||||
TableFulltextItemCount |
表 |
成功编制了全文索引的行数。
|
|||||
TableFulltextKeyColumn |
表 |
与参与全文索引定义的单列唯一索引关联的列的 ID。 0 = 表没有全文索引。
|
|||||
TableFulltextPendingChanges |
表 |
要处理的挂起更改跟踪项的数目。 0 = 不启用更改跟踪。 NULL = 表没有全文索引。
|
|||||
TableFulltextPopulateStatus |
表 |
0 = 空闲。 1 = 正在进行完全填充。 2 = 正在进行增量填充。 3 = 正在传播所跟踪的更改。 4 = 正在进行后台更新索引(例如,自动跟踪更改)。 5 = 全文索引已中止或暂停。
|
|||||
TableHasActiveFulltextIndex |
表 |
表具有活动全文索引。 1 = True 0 = False
|
|||||
TableHasCheckCnst |
表 |
表具有 CHECK 约束。 1 = True 0 = False |
|||||
TableHasClustIndex |
表 |
表具有聚集索引。 1 = True 0 = False |
|||||
TableHasDefaultCnst |
表 |
表具有 DEFAULT 约束。 1 = True 0 = False |
|||||
TableHasDeleteTrigger |
表 |
表具有 DELETE 触发器。 1 = True 0 = False |
|||||
TableHasForeignKey |
表 |
表具有 FOREIGN KEY 约束。 1 = True 0 = False |
|||||
TableHasForeignRef |
表 |
表由 FOREIGN KEY 约束引用。 1 = True 0 = False |
|||||
TableHasIdentity |
表 |
表具有标识列。 1 = True 0 = False |
|||||
TableHasIndex |
表 |
表具有任意类型的索引。 1 = True 0 = False |
|||||
TableHasInsertTrigger |
表 |
对象具有 INSERT 触发器。 1 = True 0 = False |
|||||
TableHasNonclustIndex |
表 |
表具有非聚集索引。 1 = True 0 = False |
|||||
TableHasPrimaryKey |
表 |
表具有主键。 1 = True 0 = False |
|||||
TableHasRowGuidCol |
表 |
表的 uniqueidentifier 列具有 ROWGUIDCOL。 1 = True 0 = False |
|||||
TableHasTextImage |
表 |
表具有 text、ntext 或 image 列。 1 = True 0 = False |
|||||
TableHasTimestamp |
表 |
表具有 timestamp 列。 1 = True 0 = False |
|||||
TableHasUniqueCnst |
表 |
表具有 UNIQUE 约束。 1 = True 0 = False |
|||||
TableHasUpdateTrigger |
表 |
对象具有 UPDATE 触发器。 1 = True 0 = False |
|||||
TableHasVarDecimalStorageFormat |
表 |
为 vardecimal 存储格式启用表。 1 = True 0 = False |
|||||
TableInsertTrigger |
表 |
表具有 INSERT 触发器。 >1 = 指定类型的第一个触发器的 ID。 |
|||||
TableInsertTriggerCount |
表 |
表具有指定数目的 INSERT 触发器。 >0 = INSERT 触发器的数目。 |
|||||
TableIsFake |
表 |
表不是真实的表。 它将由 SQL Server 数据库引擎根据需要在内部进行具体化。 1 = True 0 = False |
|||||
TableIsLockedOnBulkLoad |
表 |
bcp 或 BULK INSERT 作业导致表被锁。 1 = True 0 = False |
|||||
TableIsPinned |
表 |
驻留表以将其保留在数据缓存中。 0 = False SQL Server 2005 及更高版本不支持此功能。 |
|||||
TableTextInRowLimit |
表 |
text in row 允许的最大字节数。 如果未设置 text in row 选项,则为 0。 |
|||||
TableUpdateTrigger |
表 |
表具有 UPDATE 触发器。 >1 = 指定类型的第一个触发器的 ID。 |
|||||
TableUpdateTriggerCount |
表 |
表具有指定数目的 UPDATE 触发器。 > 0 = UPDATE 触发器数目。 |
|||||
TableHasColumnSet |
表 |
表具有列集。 0 = False 1 = True 有关详细信息,请参阅使用列集。 |
|||||
返回类型int
出现错误时或调用方没有查看对象的权限时,将返回 NULL。
用户只能查看符合如下条件的安全对象的元数据:该安全对象为该用户所有,或已授予该用户对该安全对象的权限。 这意味着,如果用户对对象没有任何权限,则元数据生成的内置函数(如 OBJECTPROPERTY)可能返回 NULL。 有关详细信息,请参阅元数据可见性配置。
数据库引擎假定 object_id 位于当前数据库上下文中。 引用另一个数据库中的 object_id 的查询将返回 NULL 或返回不正确的结果。 例如,在下面的查询中,当前数据库上下文为 master 数据库。 数据库引擎将尽量返回该数据库(而不是在查询中指定的数据库)中指定的 object_id 的属性值。 由于视图 vEmployee 不在 master 数据库中,该查询将返回不正确的结果。
USE master;
GO
SELECT OBJECTPROPERTY(OBJECT_ID(N'AdventureWorks2012.HumanResources.vEmployee'), 'IsView');
GO
OBJECTPROPERTY(view_id, 'IsIndexable') 可能会耗费大量的计算机资源,这是因为计算 IsIndexable 属性需要分析视图定义、规范化和局部优化。 尽管 IsIndexable 属性可以标识出能编制索引的表或视图,但在实际创建索引时,如果不能满足某些索引键要求,创建过程仍然可能会失败。 有关详细信息,请参阅 CREATE INDEX (Transact-SQL)。
如果至少添加了一个表列用于索引,则 OBJECTPROPERTY(table_id, 'TableHasActiveFulltextIndex') 将返回值 1 (true)。 只要添加了用于索引的第一列后,全文索引即可用于填充。
创建表后,表的元数据中 QUOTED IDENTIFIER 选项始终是 ON,即使在创建表时将该选项设置为 OFF。 因此,OBJECTPROPERTY(table_id, 'IsQuotedIdentOn') 将始终返回值 1 (true)。
A.验证某个对象是否为表
以下示例将测试 UnitMeasure 是否为 AdventureWorks2012 数据库中的表。
USE AdventureWorks2012;
GO
IF OBJECTPROPERTY (OBJECT_ID(N'Production.UnitMeasure'),'ISTABLE') = 1
PRINT 'UnitMeasure is a table.'
ELSE IF OBJECTPROPERTY (OBJECT_ID(N'Production.UnitMeasure'),'ISTABLE') = 0
PRINT 'UnitMeasure is not a table.'
ELSE IF OBJECTPROPERTY (OBJECT_ID(N'Production.UnitMeasure'),'ISTABLE') IS NULL
PRINT 'ERROR: UnitMeasure is not a valid object.';
GO
B.验证用户定义的标量值函数是否为确定性函数
以下示例将测试用户定义的标量值函数 ufnGetProductDealerPrice(该函数返回 money)是不是一个确定性函数。
USE AdventureWorks2012;
GO
SELECT OBJECTPROPERTY(OBJECT_ID('dbo.ufnGetProductDealerPrice'), 'IsDeterministic');
GO
结果集显示 ufnGetProductDealerPrice 是一个确定性函数。
-----
0
C.查找属于特定架构的对象
以下示例使用 SchemaId 属性返回属于架构 Production 的所有对象。
USE AdventureWorks2012;
GO
SELECT name, object_id, type_desc
FROM sys.objects
WHERE OBJECTPROPERTY(object_id, N'SchemaId') = SCHEMA_ID(N'Production')
ORDER BY type_desc, name;
GO
5.13 CHARINDEX
在一个表达式中搜索另一个表达式并返回其起始位置(如果找到)。
CHARINDEX ( expressionToFind ,expressionToSearch [ , start_location ] )
expressionToFind
包含要查找的序列的字符表达式。 expressionToFind 最多包含 8000 个字符。
expressionToSearch
要搜索的字符表达式。
start_location
表示搜索起始位置的 integer 或 bigint 表达式。 如果未指定 start_location,该参数为负数或 0,则从 expressionToSearch 开头开始搜索。
如果 expressionToSearch 具有 varchar(max)、nvarchar(max) 或 varbinary(max) 数据类型,则返回 bigint;否则,返回 int。
B.从特定位置中搜索
以下示例使用可选的start_location 参数从AdventureWorks2012 数据库的DocumentSummary 列的第五个字符开始查找vital。
DECLARE @document varchar(64);
SELECT @document = 'Reflectors are vital safety' +
' components of your bicycle.';
SELECT CHARINDEX('vital', @document, 5);
GO
下面是结果集:
-----------
16
(1 row(s) affected)
D.执行区分大小写的搜索
以下示例在'This is a Test' 中执行区分大小写的字符串'TEST' 搜索。
USE tempdb;
GO
--perform a case sensitive search
SELECT CHARINDEX ( 'TEST',
'This is a Test'
COLLATE Latin1_General_CS_AS);
下面是结果集:
-----------
0
5.14 SUBSTRING
返回 SQL Server 中的字符、二进制、文本或图像表达式的一部分。
SUBSTRING ( expression ,start , length )
expression
是 character、binary、text、ntext 或 image表达式。
start
指定返回字符的起始位置的整数或 bigint 表达式。 如果 start 小于 1,则返回的表达式的起始位置为 expression 中指定的第一个字符。 在这种情况下,返回的字符数是 start 与 length 的和减去 1 所得的值与 0 这两者中的较大值。 如果 start 大于值表达式中的字符数,将返回一个零长度的表达式。
length
是正整数或指定要返回的 expression 的字符数的 bigint 表达式。 如果 length 是负数,会生成错误并终止语句。 如果 start 与 length 的和大于 expression 中的字符数,则返回起始位置为 start 的整个值表达式。
如果 expression 是其中一个受支持的字符数据类型,则返回字符数据。 如果 expression 是支持的 binary 数据类型中的一种数据类型,则返回二进制数据。 返回的字符串类型与指定表达式的类型相同(表中显示的除外)。
指定的表达式 |
返回类型 |
char /varchar/text |
varchar |
nchar /nvarchar/ntext |
nvarchar |
binary /varbinary/image |
varbinary |
以下示例说明如何显示字符串常量abcdef 中的第二个、第三个和第四个字符。
SELECT x = SUBSTRING('abcdef', 2, 3);
下面是结果集:
x
----------
bcd
(1 row(s) affected)
B.对text、ntext 和image 数据使用SUBSTRING
注意注意
若要运行以下示例,必须安装pubs 数据库。
以下示例说明如何返回pubs 数据库的pub_info 表内每个text 和image 数据列的前10 个字符。text 数据以varchar 的形式返回,image 数据以varbinary 的形式返回。
USE pubs;
SELECT pub_id, SUBSTRING(logo, 1, 10) AS logo,
SUBSTRING(pr_info, 1, 10) AS pr_info
FROM pub_info
WHERE pub_id = '1756';
下面是结果集:
pub_id logo pr_info
------ ---------------------- ----------
1756 0x474946383961E3002500 This is sa
(1 row(s) affected)
5.15 RTRIM与LTRIM
ltrim 返回删除了前导空格之后的字符表达式。
Rtrim 截断所有尾随空格后返回一个字符串。
5.16 LEN与DATALENGTH
LEN返回指定字符串表达式的字符数,其中不包含尾随空格。
DATALENGTH返回用于表示任何表达式的字节数。对于 varchar、varbinary、text、image、nvarchar 和 ntext 数据类型,DATALENGTH 尤其有用,因为这些数据类型可以存储长度可变的数据。
5.17 quotename
返回带有分隔符的 Unicode 字符串,分隔符的加入可使输入的字符串成为有效的 SQL Server 分隔标识符。
语法QUOTENAME ( 'character_string' [ , 'quote_character' ] )
'character_string'
Unicode 字符数据构成的字符串。 character_string 是 sysname 值,并且不得超过 128 个字符。 超过 128 个字符的输入将返回 NULL。
'quote_character'
用作分隔符的单字符字符串。 可以是单引号 (')、左方括号或右方括号 ([ ]) 或者英文双引号 (")。 如果未指定 quote_character,则使用方括号。
返回类型nvarchar(258)
SELECT QUOTENAME('dbo.cte_table',''''),QUOTENAME('dbo.cte_table','"'),QUOTENAME('dbo.cte_table','[')
'dbo.cte_table',"dbo.cte_table",[dbo.cte_table]
5.18 STUFF
STUFF 函数将字符串插入到另一个字符串中。 它从第一个字符串的开始位置删除指定长度的字符;然后将第二个字符串插入到第一个字符串的开始位置。
STUFF ( character_expression , start , length , replaceWith_expression )
character_expression
一个字符串数据表达式。 character_expression 可以是常量、变量,也可以是字符列或二进制数据列。
start
一个整数值,指定删除和插入的开始位置。 如果 start 或 length 为负,则返回空字符串。 如果 start 比第一个 character_expression 长,则返回空字符串。 start 的类型可以是 bigint。
length
一个整数,指定要删除的字符数。 如果 length 比第一个 character_expression 长,则最多删除到最后一个 character_expression 中的最后一个字符。 length 的类型可以是 bigint。
replaceWith_expression
一个字符串数据表达式。 character_expression 可以是常量、变量,也可以是字符列或二进制数据列。 此表达式从 start 开始替换character_expression 的 length 个字符。
如果 character_expression 是支持的字符数据类型之一,则返回字符数据。 如果 character_expression 是支持的 binary 数据类型之一,则返回二进制数据。
以下示例从第一个字符串 abcdef 的第 2 个位置 (b) 开始删除三个字符,然后在删除位置插入第二个字符串,从而创建并返回一个字符串。
SELECT STUFF('abcdef', 2, 3, 'ijklmn');
GO
下面是结果集:
---------
aijklmnef
5.19 ISNUMERIC
确定表达式是否为有效的数值类型。
ISNUMERIC ( expression )
int
当输入表达式的计算结果为有效的 numeric 数据类型时,ISNUMERIC 返回 1;否则返回 0。 有效的 numeric 数据类型包括以下类型:
int |
numeric |
bigint |
money |
smallint |
smallmoney |
tinyint |
float |
decimal |
real |
注意 |
对于不是数字的字符(如加号 (+)、减号 (-))和有效货币符号(如美元符号 ($))字符,ISNUMERIC 将返回 1。 有关货币符号的完整列表,请参阅money 和 smallmoney (Transact-SQL)。 |
以下示例使用 ISNUMERIC 返回所有非数值的邮政编码。
USE AdventureWorks2012;
GO
SELECT City, PostalCode
FROM Person.Address
WHERE ISNUMERIC(PostalCode)<> 1;
GO