好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

sqlserver函数大全

一旦成功地从表中检索出数据,就需要进一步操纵这些数据,以获得有用或有意义的结果。这些要求包括:执行计算与数学运算、转换数据、解析数值、组合值和聚合一个范围内的值等。 下表给出了 T-SQL 函数的类别和描述。 函数类别 作用 聚合函数 执行的操作是将

一旦成功地从表中检索出数据,就需要进一步操纵这些数据,以获得有用或有意义的结果。这些要求包括:执行计算与数学运算、转换数据、解析数值、组合值和聚合一个范围内的值等。

下表给出了 T-SQL 函数的类别和描述。

函数类别

作用

聚合函数

执行的操作是将多个值合并为一个值。例如 COUNT 、 SUM 、 MIN 和 MAX 。

配置函数

是一种标量函数,可返回有关配置设置的信息。

转换函数

将值从一种数据类型转换为另一种。

加密函数

支持加密、解密、数字签名和数字签名验证。

游标函数

返回有关游标状态的信息。

日期和时间函数

可以更改日期和时间的值。

数学函数

执行三角、几何和其他数字运算。

元数据函数

返回数据库和数据库对象的属性信息。

排名函数

是一种非确定性函数,可以返回分区中每一行的排名值。

行集函数

返回可在 Transact-SQL 语句中表引用所在位置使用的行集。

安全函数

返回有关用户和角色的信息。

字符串函数

可更改 char 、 varchar 、 nchar 、 nvarchar 、 binary 和 varbinary 的值。

系统函数

对系统级的各种选项和对象进行操作或报告。

系统统计函数

返回有关 SQL Server 性能的信息。

文本和图像函数

可更改 text 和 image 的值。

函数的组成

函数的目标是返回一个值。大多数函数都返回一个标量值 (scalar value) ,标量值代表一个数据单元或一个简单值。实际上,函数可以返回任何数据类型,包括表、游标等可返回完整的多行结果集的类型。本章不准备讨论到这个深度,第 12 章将讲解如何创建和使用用户自定义函数,以返回更复杂的数据。

函数己经存在很长时间了,它的历史比 SQL 还要长。在几乎所有的编程语言中,函数调用的方式都是相同的:

Result=Function()

在 T-SQL 中,一般用 SELECT 语句来返回值。如果需要从查询中返回一个值,就可以把 SELECT 当成 输出运算符,而不用使用等号:

SELECT Function()

一个论点

对于 SQL 函数而言,参数表示输入变量或者值的占位符。函数可以有任意个参数,有些参数是必须的,而有些参数是可选的。可选参数通常被置于以逗号隔开的参数表的末尾,以便于在函数调用中去除不需要的参数。

在 SQL Server 在线图书或者在线帮助系统中,函数的可选参数用方括号表示。在下列的 CONVERT() 函数例子中,数据类型的 length 和 style 参数是可选的 :

CONVERT (data-type [(length)], expression[,style])

可将它简化为如下形式,因为现在不讨论如何使用数据类型:

CONVERT(date_type, expression[,style])

根据上面的定义, CONVERT() 函数可接受 2 个或 3 个参数。因此,下列两个例子都是正确的:

SELECT CONVERT ( Varchar ( 20 ), GETDATE ())

SELECT CONVERT ( Varchar ( 20 ), GETDATE (), 101 )

这个函数的第一个参数是数据类型 Varchar(20) ,第 2 个参数是另一个函数 GETDATE() 。 GETDATE() 函数用 datetime 数据类型将返回当前的系统日期和时间。第 2 条语句中的第 3 个参数决定了日期的样式。这个例子中的 101 指以 mm/dd/yyyy 格式返回日期。本章后面将详细介绍 GETDATE() 函数。即使函数不带参数或者不需要参数,调用这个函数时也需要写上一对括号,例如 GETDATE() 函数。注意在书中使用函数名引用函数时,一定要包含括号,因为这是一种标准形式。

确定性函数

由于数据库引擎的内部工作机制, SQL Server 必须根据所谓的确定性,将函数分成两个不同的组。这不是一种新时代的信仰,只和能否根据其输入参数或执行对函数 输出结果进行预测有关。如果函数的 输出只与输入参数的值相关,而与其他外部因素无关,这个函数就是确定性函数。如果函数的 输出基于环境条件,或者产生随机或者依赖结果的算法,这个函数就是非确定性的。例如, GETDATE() 函数是非确定性函数,因为它不会两次返回相同的值。为什么要把看起来简单的事弄得如此复杂呢?主要原因是非确定性函数与全局变量不能在一些数据库编程对象中使用 ( 如用户自定义函数 ) 。部分原因是 SQL Server 缓存与预编译可执行对象的方式。例如,即席查询可以使用任何函数,不过如果打算构建先进的、可重用的编程对象,理解这种区别很重要。

以下这些函数是确定性的:

l AVG()( 所有的聚合函数都是确定性的 )

l CAST()

l CONVERT()

l DATEADD()

l DATEDIFF()

l ASCII()

l CHAR()

l SUBSTRING()

以下这些函数与变量是非确定性的:

l GETDATE()

l @@ERROR

l @@SERVICENAME

l CURSORSTATUS()

l RAND()

在函数中使用用户变量

变量既可用于输入,也可用于 输出。在 T-SQL 中,用户变量以 @ 符号开头,用于声明为特定的数据类型。可以使用 SET 或者 SELECT 语句给变量赋值。以下的例子用于将一个 int 类型的变量 @MyNumber 传递给 SQRT() 函数:

DECLARE @MyNumber int

SET @MyNumber = 144

SELECT SQRT ( @MyNumber )

结果是 12 ,即 144 的平方根。

用 SET 给变量赋值

以下例子使用另一个 int 型的变量 @MyResult ,来捕获该函数的返回值。这个技术类似于过程式编程语言中的函数调用样式,即把 SET 语句和一个表达式结合起来,给参数赋值:

DECLARE @MyNumber int , @MyResult int

SET @MyNumber = 144

-- Assign the function result to the variable:

SET @MyResult = SQRT ( @MyNumber )

-- Return the variable value

SELECT @MyResult

用 SELECT 给变量赋值

使用 SELECT 的另一种形式也可以获得同样的结果。对变量要在赋值前要先声明。使用 SELECT 语句来替代 SET 命令的主要优点是,可以在一个操作内同时给多个变量赋值。执行下面的 SELECT 语句,通过 SELECT 语句赋值的变量就可以用于任何操作了。

DECLARE @MyNumber1 int , @MyNumber2 int ,

@MyResult1 int , @MyResult2 int

SELECT @MyNumber1 = 144 , @MyNumber2 = 121

-- Assign the function result to the variable:

SELECT @MyResult1 = SQRT ( @MyNumber1 ),

@MyResult2 = SQRT ( @MyNumber2 )

-- Return the variable value

SELECT @MyResult1 , @MyResult2

上面的例子首先声明了 4 个变量,然后用两个 SELECT 语句给这些变量赋值,而不是用 4 个 SELECT 语句给变量赋值。虽然这些技术在功能上是相同的,但是在服务器的资源耗费上,用一个 SELECT 语句给多个变量赋值一般比用多个 SET 命令的效率要高。将一个甚至多个值选进参数的限制是,对变量的赋值不能和数据检索操作同时进行。这就是上面的例子使用 SELECT 语句来填充变量,而用另外一个 SELECT 语句来检索变量中数据的原因。例如,下面的脚本就不能工作 :

DECLARE @RestockName varchar ( 50 )

SELECT ProductId

, @RestockName = Name + ':' + ProductNumber

FROM Production . Product

这个脚本会产生如下错误 :

消息 141 ,级别 15 ,状态 1 ,第 2 行

向变量赋值的 SELECT 语句不能与数据检索操作结合使用。

在查询中使用函数

函数经常和查询表达式结合使用来修改列值。这只需将列名作为参数传递给函数即可,随后函数将引用插入到 SELECT 查询的列的列表中,如下所示:

SELECT Title , NationalIDNumber , YEAR ( BirthDate ) AS BirthYear

FROM HumanResources . Employee

在这个例子中, BirthDate 列的值被作为参数传递给 YEAR() 函数。函数的结果是别名为 BirthYear 的列。

嵌套函数

我们需要的功能常常不能仅由一个函数来实现。根据设计,函数应尽量简单,用于提供特定的功能。如果一个函数要执行许多不同的操作,就变得复杂和难以使用。因此,每个函数通常仅执行一个操作,要实现所有的功能,可以将一个函数的返回值传递给另一个函数,这称为嵌套函数调用。

以下是一个简单的例子: GETDATE() 函数的作用是返回当前的日期与时间,但不能返回经过格式化的数据,因为这是 CONVERT() 函数的功能。要想同时使用这两个函数,可以把 GETDATE() 函数的 输出作为 CONVERT() 函数的输入参数。

SELECT CONVERT ( Varchar ( 20 ), GETDATE (), 101 )

聚合函数

报表的典型用途是从全部数据中提取出代表一种趋势的值或者汇总值,这就是聚合的意义。聚合函数回答数据使用者的如下问题 :

上个月鸡雏的总销售量是多少 ?

19 ~ 24 岁之间的巴西男性在食品调味品上的平均支出是多少 ?

上季度所有订单中从订购到运输的最长时间是多少 ?

收发室里仍在工作的最老的员工是谁 ?

聚合函数应用特定的聚合操作并返回一个标量值 ( 单一值 ) 。返回的数据类型对应于该列或者传递到函数中的值。聚合经常和分组、累积以及透视等表运算一起使用,生成数据分析结果。第 7 章将详细介绍这个主题,这里仅讨论简单 SELECT 查询中的一些常用函数。

聚合函数不仅可用在 SELECT 查询中,还可以和标量输入值一起使用。那么,这样做的意义是什么呢?在下列代码中,将值 15 传递给下列聚合函数,每个函数的返回值都相同:

SELECT AVG ( 15 )

SELECT SUM ( 15 )

SELECT MIN ( 15 )

SELECT MAX ( 15 )

它们都返回 15 。虽然,对同一个值求平均、求和、求最小值、求最大值,所得的结果还是那个值。如果对一个值计数,又会产生什么结果呢?

SELECT COUNT ( 15 )

得到的值是 1 ,因为函数只计数了一个值。

现在做一些有意义的事。聚合函数只有在处理结果集合中的一组数据时才有意义。每个函数都处理某列的非空值。除非使用分组操作 ( 详见第 7 章 ) ,否则不能在同一个 SELECT 语句中既返回聚合的值,又返回常规的列值。

AVG() 函数

AVG() 函数用于返回一组数值中所有非空数值的平均值。例如,表 6-2 包含了体操成绩。

体操运动员

项 目

成 绩

Sara

跳马

9.25

Cassie

跳马

Delaney

跳马

9.25

Sammi

跳马

Erika

跳马

8.60

Sara

平衡木

Cassie

平衡木

9.00

Delaney

平衡木

Sammi

平衡木

8.95

Erika

平衡木

对这些数据执行以下查询 :

SELECT AVG(Score)

结果是 8.965 。

如果有三个女孩没有完成一些项目,在表中没有记录成绩,则可用 NULL 来表示 ( 见表 6-3) 。

体操运动员

项 目

成 绩

Sara

跳马

Cassie

跳马

Delaney

跳马

NULL

Sammi

跳马

Erika

跳马

Sara

平衡木

Cassie

平衡木

NULL

Delaney

平衡木

Sammi

平衡木

NULL

Erika

平衡木

脚本:

create table #GymEvent ( Player varchar ( 10 ), [Subject] nvarchar ( 5 ), Score decimal ( 4 , 2 ))

go

insert into #GymEvent values ( 'Sara' , ' 跳马 ' , 9.25 )

insert into #GymEvent values ( 'Cassie' , ' 跳马 ' , 8.75 )

insert into #GymEvent values ( 'Delaney' , ' 跳马 ' ,NULL)

insert into #GymEvent values ( 'Sammi' , ' 跳马 ' , 8.05 )

insert into #GymEvent values ( 'Erika' , ' 跳马 ' , 8.60 )

insert into #GymEvent values ( 'Sara' , ' 平衡木 ' , 9.70 )

insert into #GymEvent values ( 'Cassie' , ' 平衡木 ' ,NULL)

insert into #GymEvent values ( 'Delaney' , ' 平衡木 ' , 9.25 )

insert into #GymEvent values ( 'Sammi' , ' 平衡木 ' ,NULL)

insert into #GymEvent values ( 'Erika' , ' 平衡木 ' , 8.85 )

go

drop table #GymEvent

在这种情况下,计算平均值时只考虑实际的数值, NULL 不参与运算,结果是 8.921429 。 但是,如果把缺少的成绩也算在内,即用数值 0 代替 NULL ,则会严重影响最终成绩 (6.245) ,她们能不能进入国家级的比赛就难说了。

COUNT() 函数

COUNT() 函数用于返回一个列内所有非空值的个数,这是一个整型值。比如,在上一个例子中,体操数据被保存在 #GymEvent 表中,要确定 Sammi 参加的项目数,则可以执行下列查询:

SELECT COUNT ( Score ) FROM #GymEvent WHERE Player = 'Sammi'

结果是 1 ,因为 Sammi 只参加了跳马比赛,她的平衡木成绩是 NULL 。

如果需要确定表中的行数,无论这些行是不是 NULL 值,都可以使用以下语法:

SELECT COUNT (*) FROM #GymEvent

以 Sammi 为例, COUNT(*) 查询如下所示 :

SELECT COUNT (*) FROM #GymEvent WHERE Player = 'Sammi'

由于 COUNT(*) 函数会忽略 NULL 值,所以这个查询的结果是 2 。

MIN() 与 MAX() 函数

MIN() 函数用于返回一个列范围内的最小非空值; MAX() 函数用于返回最大值。这两个函数可以用于大多数的数据类型,返回的值根据对不同数据类型的排序规则而定。为了说明这两个函数,假设有一个表包含了两列值,一列是整型值,另一列是字符型值,如表 6-4 所示。

IntegerColumn(int 类型 )

VarCharColumn(varChar 类型 )

2

4

4

12

19

19

脚本:

create table #Temp ( IntegerColumn int , VarCharColumn varchar ( 10 ))

go

insert into #Temp values ( 2 , '2' )

insert into #Temp values ( 4 , '4' )

insert into #Temp values ( 12 , '12' )

insert into #Temp values ( 19 , '19' )

go

drop table #Temp

如果分别调用 MIN() 与 MAX() 函数将会返回什么值呢?

select MIN ( IntegerColumn ), MAX ( IntegerColumn ) from #Temp

select MIN ( VarCharColumn ), MAX ( VarCharColumn ) from #Temp

因为 VarCharColumn 中值的存储类型为字符类型,而不是数字,所以结果以每个字符的 ASCII 值为顺序从左到右排序。这就是 12 比其他值小、而 4 比其他值大的原因。

SUM() 函数

SUM() 函数是最常用的聚合函数之一,它的功能很容易理解:和 AVG() 函数一样,它用于数值数据类型,返回一个列范围内所有非空值的总和。

配置变量

配置变量不是函数,不过它们的用法和系统函数相同。每个全局变量都能够返回 SQL Server 执行环境的标量信息。以下是一些常见的例子。

@@ERROR 变量

这个变量包含当前连接发生的最后一次错误的代码。在执行的语句没有错误时, @@ERROR 变量的值是 0 。出现标准错误时,错误是由数据库引擎引发的。所有的标准错误代码与消息都保存在 sys.messages 系统视图中,可以使用如下脚本查询:

SELECT * FROM sys . messages

定制错误可以通过调用 RAISERROR 语句来手动引发,并调用 sp_addmessage 系统存储过程将其添加到 sysmessages 表中。

以下是一个 @@ERROR 变量的简单例子。先试着将一个数除以 0 ,数据库引擎会引发标准错误号为 8134 的错误。注意查看 Results 选项卡中的查询结果。在发生错误时, Management Studio 的 Messages 选项卡将默认显示在 Results 选项卡的上面:

SELECT 5 / 0

SELECT @@ERROR

在成功检索 @@ERROR 的值后, @@ERROR 的值将返回 0 ,因为 @@ERROR 只保存了上次执行的语句的错误代码。如果希望检索更多的错误信息,可以使用如下脚本从 sysmessages 视图中得到:

SELECT 5 / 0

SELECT * FROM master . dbo . sysmessages WHERE error = @@ERROR

本节的后面部分内容将说明如何通过使用错误函数来更高效地返回错误数据。

除了美国英语之外, SQL Server 还默认安装了其他语言。每种语言专用的错误消息都有一个语言标识符 (mslangid) ,对应于 syslanguages 表中的一种语言,如下图所示。

error

severity

dlevel

description

msglangid

8134

16

0

Divide by zero error encountered.

1033

8134

16

0

Fehler aufgrund einer Division durch Null.

1031

8134

16

0

Division par z é ro.

1036

8134

16

0

0 除算エラーが発生しました。

1041

8134

16

0

Error de divisi ó n entre cero.

3082

8134

16

0

Errore di divisione per zero.

1040

8134

16

0

Обнаружена ошибка : деление на ноль .

1049

8134

16

0

Erro de divisão por zero.

1046

8134

16

0

發現除以零的錯誤。

1028

8134

16

0

0 ?? ??? ??? ?????? .

1042

8134

16

0

遇到以零作除数错误。

2052

属性名 mslangid 被非正式地定义为 Microsoft Global Language Identifier 。微软公司用这个标识符来标识一种语言或语言和国家的组合,微软公司把语言和国家的组合定义为地区。例如,在随 SQL Server 安装的英语中,美国英语的 mslangid 是 1033 ,英国英语的 mslangid 是 2057 。要检索出所有已安装的、支持的语言,可以执行下面的查询:

SELECT alias , name , msglangid

FROM sys . syslanguages

@@SERVICENAME 变量

这个变量是用于执行和维护当前 SQL Server 实例的 Windows 服务名。它通常返回 SQL Server 默认实例 MSSQLSERVER ,但 SQL Server 的指定实例有唯一的服务名。例如在名为 WoodVista 的计算机上有两个 SQL Server 实例:默认实例和指定实例 AughtEight 。如在默认实例上检索 @@SERVICENAME 全局变量的内容,将返回 MSSQLSERVER ,但在指定实例上检索,会返回 AUGHTEIGHT 。

@@TOTAL_ERRORS 变量

这个变量用于记录从打开当前连接开始发生的总错误次数。和 @@ERROR 变量一样,它对每个用户会话是唯一的,并将在连接关闭时被重置。

@@TOTAL_READ 变量

这个变量记录从打开当前连接时开始计算的磁盘读取总数。 DBA 使用这个变量查看磁盘读取活动的情况。

@@VERSION 变量

这个变量包含当前 SQL Server 实例的完整版本信息。

SELECT @@VERSION

比如,对于运行在 Windows 7 上的 SQL Server 2008 开发版实例,以上脚本能够返回如下信息 :

Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) Jul 9 2008 14:43:34 Copyright (c) 1988-2008 Microsoft Corporation Enterprise Edition on Windows NT 6.1 (Build 7600: )

实际的版本号是一个简单的整型值,它在微软公司内部使用。而发行的产品可能有其他的商标名。在本例中, SQL Server 2005 的版本是 9 , SQL Server 2008 的版本是 10 。 Windows XP Professional 显示为 Windows NT 5.l 版,而 Vista 显示为 6.0 版。构建号用于内部控制,反映 beta 版和预览版以及正式发行后的补丁包的变化。

错误函数

前面学习了如何使用 @@ERROR 全局变量来检索错误信息。而返回所有错误数据的更好方法是使用错误函数。这些函数返回的信息可以存储在错误跟踪表中,以供错误审核。错误函数嵌套在错误处理例程中。第 11 章将详细讨论错误处理,其实通过使用嵌套在 TRY 和 END TRY 语句中的代码块,后跟一个放在 CATCH 和 END CATCH 语句中的代码块就可以实现错误处理。

--Try to do something

BEGIN TRY

SELECT 5 / 0

END TRY

--If it causes an error, do this

BEGIN CATCH

PRINT ERROR_MESSAGE ()

END CATCH

所谓的错误捕获,其实就是这个意思。如果运行上面的示例,将不会出现可识别的错误,因为错误将被捕获并在 CATCH 语句块中进行处理。在编写错误处理代码时, SQL 程序员必须把这些代码放在会引发系统错误的 catch 代码块中。

下列几个错误函数用于返回错误的特定信息:

函数

说明

ERROR_MESSAGE ()

返回错误的描述。

ERROR_NUMBER ()

返回错误号。

ERROR_SEVERITY ()

返回错误的严重级别。错误的严重级别是一个从 0 到 25 的整数。

ERROR_STATE ()

返回错误的状态号。错误状态是一个整数,可以唯一地表示系统错误的原因。

ERROR_LINE ()

返回例程中导致出错的行号。

ERROR_PROCEDURE ()

返回发生错误的存储过程名或触发器名。

下表简要描述了严重级别。

严 重 级 别

说 明

0 ~ 10

信息性消息。不会引发系统错误

11 ~ 16

用户可以更正的错误,例如违反了外键或主键规则

17

非致命的、不重要的资源错误

18

非致命的内部错误

19

致命的、不重要的资源错误

20

当前进程中的致命错误

21

所有进程中的致命数据库错误

22

致命的表完整性错误

23

致命的数据库完整性错误

24

致命的硬件错误

25

致命的系统错误

下面脚本使用 T-SQL 的内置错误处理功能,来捕获和 输出遇到除 0 错误时返回的错误数据。 SELECT 命令的结果将显示在 Management Studio 的消息选项卡中。

--Try to do something

BEGIN TRY

SELECT 5 / 0

END TRY

--If it causes an error, do this

BEGIN CATCH

SELECT ERROR_MESSAGE (), ERROR_NUMBER (), ERROR_SEVERITY (),

ERROR_STATE (), ERROR_LINE (), ERROR_PROCEDURE ()

END CATCH

可以看出,执行这个脚本会在消息选项卡中返回有关错误的更多详细信息,而不仅仅是错误号本身。

ERROR_PROCEDURE() 函数不能返回过程名,因为错误是在 ad-hoc 查询中生成的。

转换函数

数据类型转换可以通过 CAST() 和 CONVERT() 函数来实现。大多数情况下,这两个函数是重叠的,它们反映了 SQL 语言的演化历史。这两个函数的功能相似,不过它们的语法不同。虽然并非所有类型的值都能转变为其他数据类型,但总的来说,任何可以转换的值都可以用简单的函数实现转换。

CAST() 函数

CAST() 函数的参数是一个表达式,它包括用 AS 关键字分隔的源值和目标数据类型。以下例子用于将文本字符串 '123' 转换为整型 :

SELECT CAST ( '123' AS int )

返回值是整型值 123 。如果试图将一个代表小数的字符串转换为整型值,又会出现什么情况呢?

SELECT CAST ( '123.4' AS int )

CAST() 函数和 CONVERT() 函数都不能执行四舍五入或截断操作。由于 123.4 不能用 int 数据类型来表示,所以对这个函数调用将产生一个错误 :

Server: Msg 245, Level 16, State 1, Line 1

Syntax error converting the varchar value

'123.4' to a column of data type int .

在将 varchar 值 '123.4' 转换成数据类型 int 时失败。

要返回一个合法的数值,就必须使用能处理这个值的数据类型。对于这个例子,存在多个可用的数据类型。如果通过 CAST() 函数将这个值转换为 decimal 类型,需要首先定义 decimal 值的精度与小数位数。在本例中,精度与小数位数分别为 9 与 2 。精度是总的数字位数,包括小数点左边和右边位数的总和。而小数位数是小数点右边的位数。这表示本例能够支持的最大的整数值是 9999999 ,而最小的小数是 0.01 。

SELECT CAST ( '123.4' AS decimal ( 9 , 2 ))

decimal 数据类型在结果网格中将显示有效小数位 :123.40

精度和小数位数的默认值分别是 18 与 0 。如果在 decimal 类型中不提供这两个值, SQL Server 将截断数字的小数部分,而不会产生错误。

SELECT CAST ( '123.4' AS decimal )

结果是一个整数值: 123

在表的数据中转换数据类型是很简单的。下面的例子使用 Product 表,首先执行如下查询:

SELECT ProductNumber , ProductLine , ProductModelID

FROM Production . Product

WHERE ProductSubcategoryID 4

假定产品经理已经创建了一个系统,用于唯一地标识生产出来的每辆自行车,以便跟踪其型号、类型和类别。他决定合并产品号、产品生产线标识符、产品型号标识符和一个顺序号,为生产出来的每辆自行车创建一个唯一的序列号。在这个过程的第一步,他要求提供包括除顺序号之外的所有属性的所有可能产品的根标识符。

如果使用下面的表达式,就不能得到希望的结果,如图 6-2 所示。

SELECT ProductNumber

+ '-'

+ ProductLine

+ '-'

+ ProductModelID AS BikeSerialNum

FROM Production . Product

WHERE ProductSubcategoryID 4

消息 245 ,级别 16 ,状态 1 ,第 1 行

在将 nvarchar 值 'BK-R93R-62-R -' 转换成数据类型 int 时失败。

我们没有得到希望的结果,而得到了有点奇怪的错误消息:请把 nvarchar 值转换为 int 。因为之前我们没有要求进行任何转换,所以这个错误很奇怪。这个查询的问题在于我们试图利用第一个连接符来连接字符值 ProductNumber ,利用第二个连接符连接另一个字符值 ProductLine ,最后连接的是 ProductModelID 字符值 ( 它是一个整数 ) 。

查询引擎会把连接符当成一个数学运算符,而不是一个字符。不管结果是什么,都需要更正这个表达式,以确保使用正确的数据类型。以下表达式执行了必要的类型转换,返回如图 6-3 所示的结果:

SELECT ProductNumber

+ '-'

+ ProductLine

+ '-'

+ CAST ( ProductModelID AS char ( 4 )) AS BikeSerialNum

FROM Production . Product

WHERE ProductSubcategoryID 4

如果把整型值转换为字符类型就不会增加多余的空格了。查询引擎将把这些值用加号和连接符组合在一起,进行字符串连接运算,而不是和前面的数值进行加法或者减法运算了。

CONVERT() 函数

对于简单类型转换, CONVERT() 函数和 CAST() 函数的功能相同,只是语法不同。 CAST() 函数一般更容易使用,其功能也更简单。 CONVERT() 函数的优点是可以格式化日期和数值,它需要两个参数:第 1 个是目标数据类型,第 2 个是源数据。以下的两个例子和上一节的例子类似:

SELECT CONVERT ( int , '123' )

SELECT CONVERT ( decimal ( 9 , 2 ), '123.4' )

CONVERT() 函数还具有一些改进的功能,它可以返回经过格式化的字符串值,且可以把日期值格式化成很多形式。有 28 种预定义的符合各种国际和特殊要求的日期与时间 输出格式。下表列出了这些日期格式。

如果 expression 为 date 或 time 数据类型,则 style 可以为下表中显示的值之一。其他值作为 0 进行处理。 SQL Server 使用科威特算法来支持阿拉伯样式的日期格式。

yy(1)

yyyy

标准

输入 / 输出 (3)

-

0 或 100 (1, 2)

默认

mon dd yyyy hh:miAM (或 PM )

1

101

美国

mm/dd/yyyy

2

102

ANSI

yy.mm.dd

3

103

英国 / 法国

dd/mm/yyyy

4

104

德国

dd.mm.yy

5

105

意大利

dd-mm-yy

6

106 (1)

-

dd mon yy

7

107 (1)

-

mon dd, yy

8

108

-

hh:mi:ss

-

9 或 109 (1, 2)

默认设置 + 毫秒

mon dd yyyy hh:mi:ss:mmmAM (或 PM )

10

110

美国

mm-dd-yy

11

111

日本

yy/mm/dd

12

112

ISO

yymmdd

yyyymmdd

-

13 或 113 (1, 2)

欧洲默认设置 + 毫秒

dd mon yyyy hh:mi:ss:mmm(24h)

14

114

-

hh:mi:ss:mmm(24h)

-

20 或 120 (2)

ODBC 规范

yyyy-mm-dd hh:mi:ss(24h)

-

21 或 121 (2)

ODBC 规范(带毫秒)

yyyy-mm-dd hh:mi:ss.mmm(24h)

-

126 (4)

ISO8601

yyyy-mm-ddThh:mi:ss.mmm (无空格)

-

127(6, 7)

带时区 Z 的 ISO8601 。

yyyy-mm-ddThh:mi:ss.mmmZ

(无空格)

-

130 (1, 2)

回历 (5)

dd mon yyyy hh:mi:ss:mmmAM

-

131 (2)

回历 (5)

dd/mm/yy hh:mi:ss:mmmAM

1. 这些样式值将返回不确定的结果。包括所有 (yy) (不带世纪数位)样式和一部分 (yyyy) (带世纪数位)样式。

2. 默认值( style 0 或 100 、 9 或 109 、 13 或 113 、 20 或 120 以及 21 或 121 )始终返回世纪数位 (yyyy) 。

3. 转换为 datetime 时输入;转换为字符数据时 输出。

4. 为用于 XML 而设计。对于从 datetime 或 smalldatetime 到字符数据的转换,其 输出格式如上一个表所述。

5. 回历是有多种变体的日历系统。 SQL Server 使用科威特算法。

a) 默认情况下, SQL Server 基于截止年份 2049 年来解释两位数的年份。换言之,就是将两位数的年份 49 解释为 2049 ,将两位数的年份 50 解释为 1950 。许多客户端应用程序(如基于自动化对象的应用程序)都使用截止年份 2030 年。 SQL Server 提供了 [ 两位数年份截止 ] 配置选项,可通过此选项更改 SQL Server 使用的截止年份,从而对日期进行一致处理。建议您指定四位数年份。

6. 仅支持从字符数据转换为 datetime 或 smalldatetime 。仅表示日期或时间成分的字符数据转换为 datetime 或 smalldatetime 数据类型时,未指定的时间成分设置为 0.000 ,未指定的日期成分设置为 1900-01-01 。

7. 使用可选的时间区域指示符 (Z) 更便于将具有时区信息的 XML datetime 值映射到没有时区的 SQL Server datetime 值。 Z 是时区 UTC-0 的指示符。其他时区则以 + 或 - 方向的 HH:MM 偏移量来指示。例如: 2006-12-12T23:45:12-08:00 。

从 smalldatetime 转换为字符数据时,包含秒或毫秒的样式将在这些位置上显示零。使用相应的 char 或 varchar 数据类型长度从 datetime 或 smalldatetime 值转换时,可截断不需要的日期部分。

从样式包含时间的字符数据转换为 datetimeoffset 时,将在结果末尾追加时区偏移量。

这个函数的第三个参数是可选的,该参数用于接收格式代码整型值。表中的例子用于对 DateTime 数据类型进行转换。在转换 SmallDateTime 数据类型时,格式不变,但一些元素会显示为 0 ,因为该数据类型不支持毫秒。以下的脚本例子将 输出格式化的日期:

SELECT 'Default Date:' + CONVERT ( Varchar ( 50 ), GETDATE (), 100 )

Default Date: Apr 25 2005 1:05PM

SELECT 'US Date:' + CONVERT ( Varchar ( 50 ), GETDATE (), 101 )

US Date: 04/25/2005

SELECT 'ANSI Date:' + CONVERT ( Varchar ( 50 ), GETDATE (), 103 )

ANSI Date: 2005.04.25

SELECT 'UK/French Date:' + CONVERT ( Varchar ( 50 ), GETDATE (), 103 )

UK/French Date: 25/04/2OO5

SELECT 'German Date:' + CONVERT ( Varchar ( 50 ), GETDATE (), 104 )

German Date: 25.04.2005

格式代码 0 , 1 和 2 也可用于数字类型,它们对小数与千位分隔符格式产生影响。而不同的数据类型所受的影响是不一样的。一般来说,使用格式代码 0( 或者不指定这个参数的值 ) ,将返回该数据类型最惯用的格式。使用 1 或者 2 通常显示更为详细或者更精确的值。以下例子使用格式代码 0 :

DECLARE @Num Money

SET @Num = 1234.56

SELECT CONVERT ( varchar ( 50 ), @Num , 0 )

返回结果如下 :

1234.56

使用值 1 则返回如下结果 :

1,234.56

使用值 2 则返回如下结果 :

1234.5600

以下例子和上例相同,但是使用 Float 类型 :

DECLARE @Num float

SET @Num = 1234.56

SELECT CONVERT ( varchar ( 50 ), @Num , 2 )

使用值 0 不会改变所提供的格式,但是使用值 1 或 2 将返回以科学计数法表示的数字,后者使用了 15 位小数:

STR() 函数

这是一个将数字转换为字符串的快捷函数。这个函数有 3 个参数:数值、总长度和小数位数。如果数字的整数位数和小数位数 ( 要加上小数点占用的一个字符 ) 的总和小于总长度,对结果中左边的字符将用空格填充。在下面第 1 个例子中,包括小数点在内一共是 5 个字符。结果显示在网格中,显然左边的空格被填充了。这个调用指定,总长度为 8 个字符,小数位为 4 位:

SELECT STR ( 123.4 , 8 , 4 )

结果值的右边以 0 填充: 123.4000 。

下面给函数传递了一个 10 字符的值,并指定结果包含 8 个字符,有 4 个小数位:

SELECT STR ( 123.456789 , 8 ,

查看更多关于sqlserver函数大全的详细内容...

  阅读:67次