CAST 和 CONVERT (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsMicrosoft Fabric中的SQL分析端点Microsoft Fabric中的仓库Microsoft Fabric中的SQL数据库

这些函数将表达式由一种数据类型转换为另一种数据类型。

语法

CAST 语法:

CAST ( expression AS data_type [ ( length ) ] )

CONVERT 语法:

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

Transact-SQL 语法约定

参数

expression

任何有效的表达式。

data_type

目标数据类型。 这包括 xml、bigint 和sql_variant 。 不能使用别名数据类型。

长度

指定目标数据类型长度的可选整数,适用于允许用户指定长度的数据类型。 默认值为 30。

style

一个整数表达式,指定函数如何 CONVERT 平译 表达式。 对于样式值, NULL返回 NULL 。 data_type 确定范围。

返回类型

返回转换为 data_type 的 expression 。

日期和时间样式

对于日期或时间数据类型的 expression,style 可以具有下表所示的某个值。 其他值则被处理为 0。 从SQL Server 2012(11.x)开始,在从日期和时间类型转换为datetimeoffset时,唯一支持的样式是01或。 所有其他转换样式均返回错误 9809。

注意

SQL Server 数据库引擎 支持阿拉伯格式的日期格式,采用 Kuwaiti 算法。

不带世纪数位 (yy) 1 带世纪数位 (yyyy) 标准 输入/输出 3
- 0或1001,2 datetime 和 smalldatetime 的默认值 MMM dd yyyy hh:mmtt (tt 是 AM 或 PM)
1 101 美国 1 = MM/dd/yy
101 = MM/dd/yyyy
2 102 ANSI 2 = yy.MM.dd
102 = yyyy.MM.dd
3 103 英国/法国 3 = dd/MM/yy
103 = dd/MM/yyyy
4 104 德语 4 = dd.MM.yy
104 = dd.MM.yyyy
5 105 意大利语 5 = dd-MM-yy
105 = dd-MM-yyyy
6 106 1 - 6 = dd MMM yy
106 = dd MMM yyyy
7 107 1 - 7 = MMM dd, yy
107 = MMM dd, yyyy
8 或 24 108 - HH:mm:ss
- 9或1091,2 默认格式 + 毫秒 MMM dd yyyy hh:mm:ss:ffftt (tt 是 AM 或 PM)
10 110 美国 10 = MM-dd-yy
110 = MM-dd-yyyy
11 111 Japan 11 = yy/MM/dd
111 = yyyy/MM/dd
12 112 ISO 12 = yyMMdd
112 = yyyyMMdd
- 13或1131,2 欧洲默认格式 + 毫秒 dd MMM yyyy HH:mm:ss:fff(24 小时制)
14 114 - HH:mm:ss:fff(24 小时制)
- 20 或 1202 ODBC 规范 yyyy-MM-dd HH:mm:ss(24 小时制)
- 21或 25121 或 2 time、date、datetime2 和 datetimeoffset 的 ODBC 规范(用毫秒表示)默认值 yyyy-MM-dd HH:mm:ss.fff(24 小时制)
22 - 美国 MM/dd/yy hh:mm:ss tt (tt 是 AM 或 PM)
- 23 ISO8601 yyyy-MM-dd
- 126 4 ISO8601 yyyy-MM-ddTHH:mm:ss.fff(无空格)6
- 127 8, 9 包括时区 Z 的 ISO8601 yyyy-MM-ddTHH:mm:ss.fffZ(无空格)6
- 130 1,2 回历 5 dd MMMM yyyy hh:mm:ss:ffftt 7
- 131 2 回历 5 dd/MM/yyyy hh:mm:ss:ffftt

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

2 默认值(0或 100,9或109,13或113,或,20或212325120,,或,或)121总是返回世纪()。yyyy

重要

默认情况下,SQL Server 数据库引擎 会基于 2049 年的截止年份来解释两位数年份。 这意味着数据库引擎将两位数的49年解读为2049年,将两位数的50年解读为1950年。 许多客户端应用程序(包括基于自动化对象的应用程序)都使用截止年份 2030 年。 数据库引擎 提供两位数的截止年配置选项,以更改 数据库引擎 使用的截止年份。 这允许对日期进行一致处理。 建议您指定四位数年份。

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

4 为用于 XML 而设计。 对于从 datetime 或 smalldatetime 到字符数据的转换,请参阅上一个表,查看输出格式 。

5 回历是有多种变体的日历系统。 数据库引擎 采用了科威特算法。

6 毫秒 (fff) 值为 0 时,不会显示毫秒小数部分的值。 例如,值 2022-11-07T18:26:20.000 显示为 2022-11-07T18:26:20。

7 在此样式中, MMMM 表示全月名称的多标记 Hijri Unicode 表示形式。 该值在 SSMS 的默认 US 安装中不会正确呈现。

8 仅在从字符数据强制转换到 datetime 或 smalldatetime 时提供支持。 仅表示日期或时间成分的字符数据强制转换为 datetime 或 smalldatetime 数据类型时,未指定的时间成分设置为 ,未指定的日期成分设置为 。

9 使用可选的时区指示器Z,以便将带有时区信息的 XML datetime 值映射到 数据库引擎 中没有时区的 datetime 值。 Z 指示时区 UTC-0。 HH:mm 或 + 方向的 - 偏移量则指示其他时区。 例如:2022-12-12T23:45:12-08:00。

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

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

float 和 real 样式

对于 float 或 real 表达式,style 可能具有下表显示的值之一。 其他值则被处理为 0。

值 输出
0(默认值) 最多包含 6 位。 根据需要使用科学记数法。
1 始终为 8 位值。 始终使用科学记数法。
2 始终为 16 位值。 始终使用科学记数法。
3 始终为 17 位值。 用于无损转换。 使用此样式,可以保证每个不重复的 float 或 real 值转换为不重复的字符串。

适用于:SQL Server 2016(13.x)及更高版本以及 Azure SQL 数据库。
126、128、129 出于传统原因包括在内。 请勿将这些值用于新的开发过程。

money 和 smallmoney 样式

对于 money 和 smallmoney 表达式,style 可能具有下表显示的值之一。 其他值则被处理为 0。

值 输出
0(默认值) 小数点左侧每三位数字之间不以逗号分隔,小数点右侧取两位数

示例:4235.98。
1 小数点左侧每三位数字之间以逗号分隔,小数点右侧取两位数

示例:3,510.92。
2 小数点左侧每三位数字之间不以逗号分隔,小数点右侧取四位数

示例:4235.9819。
126 等价于样式 2,当转换为 char(n) 或 varchar(n)时

xml 样式

对于 xml 表达式,style 可能具有下表显示的值之一。 其他值则被处理为 0。

值 输出
0(默认值) 使用默认的分析行为,即放弃无用的空格,且不允许使用内部 DTD 子集。

注意:在转换为XML数据类型时,数据库引擎对无关紧要的空白处理方式与XML 1.0不同。 欲了解更多信息,请参见 创建XML数据实例。
1 保留无用空格。 此样式设置将默认xml:space 处理设置为匹配 xml:space="preserve" 的行为。
2 启用有限的内部 DTD 子集处理。

如果启用,则服务器可使用内部 DTD 子集提供的以下信息来执行非验证分析操作。

- 应用属性的默认值
- 解析并展开内部实体引用
- 检查 DTD 内容模型来确定语法的正确性

分析器忽略外部 DTD 子集。 此外,它不会评估 XML 声明,判断 独立 属性是否有 a yes 或 no 值。 相反,它将 XML 实例解析为独立文档。
3 保留无用空格,并启用有限的内部 DTD 子集处理。

二进制样式

对于 binary(n)、char(n)、varbinary(n)或 varchar(n)表达式,样式可以具有下表中显示的值之一。 表格中未列出的样式值会返回错误。

值 输出
0(默认值) 将 ASCII 字符转换为二进制字节,或者将二进制字节转换为 ASCII 字符。 每个字符或字节按照 1:1 进行转换。

对于二进制 data_type,字符 0x 会加到结果的左侧。
1、2 对于二进制 data_type,则表达式必须为字符表达式。 表达式必须有偶数个十六进制数字(0, , 1, , c98BDECFAabedf723456 如果 样式设置为1,表达式的前两个字符必须是 0x 。 如果表达式中包含的字符数为奇数或者包含任何无效的字符,则会引发错误。

如果转换后的表达式长度大于 data_type 长度,则会在右侧截断结果。

如果固定长度 data_types 大于转换后的结果,则在结果右侧添加零。

字符类型的 data_type 要求二进制表达式。 每个二进制字符均转换为两个十六进制字符。 假设转换后的表达式长度大于 data_type 长度。 在这种情况下,它会被截断。

对于固定大小的字符类型 data_type ,并且转换后的结果长度小于其 data_type 长度,则会在转换后的表达式右侧添加空格,以使十六进制数字的个数保持为偶数 。

0x字符不会被添加到转换后的结果左侧以增加样式2。

隐式转换

隐式转换不需要规范 CAST 函数或 CONVERT 函数。 显示转换需要规范 CAST 函数或 CONVERT 函数。 下图展示了 数据库引擎 系统提供数据类型允许的所有显式和隐式数据类型转换。 这些包括 bigint、sql_variant、xml、hierarchyid、geography、geometry、json 和 vector。 json 和矢量数据类型仅在 SQL Server 2025(17.x)、Azure SQL 数据库、Azure SQL 托管实例 以及 Microsoft Fabric 中的 SQL 数据库中提供。 从 sql_variant 数据类型到赋值时没有隐式转换,但有隐式转换到 sql_variant。

图示显示了哪些 SQL Server 数据类型之间的转换是显式的、隐式的或不允许的,包括 hierarchyid、geography、geometry、json 和 vector 数据类型。

上图展示了数据库引擎允许的所有显式和隐式转换,但转换所得的数据类型取决于所执行的操作:

  • 对于显式转换,语句本身会确定生成的数据类型。
  • 对于隐式转换,赋值语句(例如设置变量的值或在列中插入值)将产生由变量声明或列定义所定义的数据类型。
  • 对于比较运算符或其他表达式,结果数据类型取决于数据类型优先级的规则。

对于某些数据类型,结果取决于数据类型的声明方式:

  • 十进制和数值:数据库引擎将精度和尺度的组合视为不同的数据类型。 它们之间的转换可以是隐含的。 小数位数多于目标刻度的数值会四舍五入且无误差。 对于目标精度来说过大,则误差为8115,除非 ARITHABORT 和 ANSI_WARNINGS 都 OFF为;那么结果为 NULL。
  • 你不能把 varchar(max)、nvarchar(max) 和 varbinary(max)转换成 sql_variant。
  • 不允许在不同CLR用户自定义类型之间转换。
  • 支持无类型 XML 与类型 XML 之间隐式转换,以及使用相同 XML 模式集合与相同DOCUMENT或 CONTENT facet 的类型 XML 值之间的隐式转换。
  • 不同XML模式集合之间的转换,或不同 DOCUMENT 与 CONTENT 面之间的转换必须是显式的。 不允许在 CLR 用户自定义类型与类型化 XML 之间转换。
  • 只有当尺寸和基类型(float32或float16)相同时,才允许向量值之间的转换。

图表显示允许的转换仍可能因特定值失败,例如字符串非有效JSON,或维度不同向量。 图像、ntext、text、xml、地理、几何、json和矢量数据类型的值无法与等于(=)算符进行比较,即使这两个值的数据类型相同。

提示

有关转换中数据类型优先级的影响的实际示例可在本部分后面看到。

在 datetimeoffset 与字符类型 char、nchar、nvarchar 和 varchar 之间转换时,转换后的时区偏移量部分的 和 都应始终为两个数字。 例如 -08:00。

nchar 和 nvarchar 数据类型以 UTF-16 编码存储 Unicode 数据,该编码始终使用偶数字节。 在将 二进制 或 变进制 转换成 或从nchar 或 nvarchar转换时请谨慎。 例如,以下转换不会返回十六进制值。41 它返回一个十六进制值 4100:

SELECT CAST (CAST (0x41 AS NVARCHAR) AS VARBINARY);

有关详细信息,请参阅 排序规则和 Unicode 支持。

大值数据类型

大值数据类型具有与小值数据类型相同的隐式和显式转换行为 - 特别是 nvarchar、varbinary 和 varchar 数据类型 。 但是,请考虑以下原则:

  • 从 image 转换到 varbinary(max) 以及从 varbinary(max) 转换到 image 属于隐式转换操作,同样的还有 text 与 varchar(max) 之间的转换和 ntext 与 nvarchar(max) 之间的转换 。
  • 从大值数据类型(如 varchar(max))到小值数据类型(如 varchar)的转换是隐式转换,但如果大值的大小超过小值数据类型的指定长度,则产生截断 。
  • 从 nvarchar、varbinary 或 varchar 到其相应的大值数据类型的转换都是隐式转换 。
  • 从 sql_variant 数据类型到大值数据类型的转换是显式转换。
  • 大值数据类型不能转换为 sql_variant 数据类型。

有关从 XML 数据类型转换的更多信息,请参见 创建 XML 数据实例。

XML 数据类型

将 xml 数据类型显式或隐式转换为字符串或二进制数据类型时,xml 数据类型的内容将根据一组确定的规则进行序列化 。 有关这些规则的信息,请参见 “定义XML数据的序列化”。 有关从其他数据类型转换为 XML 数据类型的信息,请参见 创建XML数据实例。

text 和 image 数据类型

text 和 image 数据类型不支持自动进行数据类型转换。 可以显式将 text 数据转换为字符数据,将 image 数据转换为 binary 或 varbinary,但是最大长度为 8000 字节 。 如果你尝试错误的转换,比如试图将包含字母的字符表达式转换为整数,数据库引擎 会返回错误信息。

输出排序规则

如果 CAST 或 CONVERT 函数输出字符串,并且接收字符串输入,则输出将与输入具有相同的排序规则和排序规则标签。 如果输入不是字符串,则输出采用数据库的默认排序规则以及强制默认的排序规则标签。 如需更多详情,请参阅排序规则优先级。

要为输出分配不同的排序,将该子句应用于 COLLATE or CAST 函数的结果表达式CONVERT。 例如:

SELECT CAST ('abc' AS VARCHAR (5)) COLLATE French_CS_AS;

截断结果和舍入结果

将字符或二进制表达式(binary、char、nchar、nvarchar、varbinary 或 varchar)转换为不同数据类型的表达式时,转换操作可能会截断输出数据,仅显示部分输出数据,或返回错误 。 如果结果太短无法显示,就会出现这种情况。 会截断到 binary、char、nchar、nvarchar、varbinary 或 varchar 的转换,除了下表中显示的转换 。

被转换的数据类型 转换为的数据类型 结果
int、smallint 或 tinyint 煳
varchar
长度太短而无法显示
nchar
nvarchar
错误 1
money、smallmoney、numeric、decimal、float 或 real 煳
varchar
错误 1
nchar
nvarchar
错误 1

1 因为结果长度太短无法显示而返回错误。

SQL Server 数据库引擎保证,只有往返转换,也就是将数据类型从原始数据类型转换回来的转换,才能在不同版本之间得到相同的值。 以下示例显示的即是这样的往返转换:

DECLARE @myval AS DECIMAL (5, 2);
SET @myval = 193.57;

SELECT CAST (CAST (@myval AS VARBINARY (20)) AS DECIMAL (10, 5));

-- Or, using CONVERT
SELECT CONVERT (DECIMAL (10, 5), CONVERT (VARBINARY (20), @myval));
GO

警告

请勿构造 binary 值然后将其转换为数值数据类型类别的一种数据类型。 数据库引擎 并不保证在不同版本的 SQL Server 之间,十进制或数字数据类型转换为二进制的结果是相同的。

以下示例显示了由于太小而无法显示的结果表达式。

USE AdventureWorks2025;
GO

SELECT p.FirstName,
       p.LastName,
       SUBSTRING(p.Title, 1, 25) AS Title,
       CAST (e.SickLeaveHours AS CHAR (1)) AS [Sick Leave]
FROM HumanResources.Employee AS e
     INNER JOIN Person.Person AS p
         ON e.BusinessEntityID = p.BusinessEntityID
WHERE NOT e.BusinessEntityID > 5;
GO

结果集如下。

FirstName   LastName      Title   Sick Leave
---------   ------------- ------- --------`
Ken         Sanchez       NULL   *
Terri       Duffy         NULL   *
Roberto     Tamburello    NULL   *
Rob         Walters       NULL   *
Gail        Erickson      Ms.    *

当你转换小数点不同数据类型时,数据库引擎有时会返回截断的结果值,有时则返回四舍五入的结果。 此表显示了此行为。

源 目标 行为
数值的 数值的 圆形
数值的 int 截断
数值的 钱 圆形
钱 int 圆形
钱 数值的 圆形
漂浮 int 截断
漂浮 数值的 第 1 轮
漂浮 日期/时间 圆形
日期/时间 int 圆形

1 如果将使用科学记数法的 float 值转换为 decimal 或 numeric 时,转换会限制为只有 17 位精度的值。 精度高于 17 的任何值都将舍入为零。

例如,10.6496 和 -10.6496 这两个值在转换为 整数 类型或 数 值类型时可能会被截断或四舍五入:

SELECT CAST (10.6496 AS INT) AS trunc1,
       CAST (-10.6496 AS INT) AS trunc2,
       CAST (10.6496 AS NUMERIC) AS round1,
       CAST (-10.6496 AS NUMERIC) AS round2;

查询结果显示在下表中:

trunc1 trunc2 round1 round2
10 -10 11 -11

在进行数据类型转换时,若目标数据类型的小数位数小于源数据类型的小数位数,则该值将进行舍入。 例如,此转换返回 $10.3497:

SELECT CAST (10.3496847 AS MONEY);

数据库引擎 在将非数字 char、nchar、nvarchar 或 varchar 数据转换为十进制、float、int、数值时,会返回错误信息。 当空字符串() 转换为数字或十进制时,数据库引擎 也会返回错误。

某些日期时间的转换具有不确定性

从 string 到 datetime 的转换为不确定性转换的样式如下所示:

  • 以下100所有风格
  • 106
  • 107
  • 109
  • 113
  • 130

1 除样式 20 和 21

有关详细信息,请参阅文字日期字符串转换为日期值的不确定性转换。

补充字符(代理项对)

从 SQL Server 2012 (11.x) 开始,使用增补字符 (SC) 排序规则时,从 nchar 或 nvarchar 到更小长度的 nchar 或 nvarchar 类型的 CAST 操作将不会在代理项对内截断。 相反,该操作会在增补字符前面截断。 例如,以下代码段导致 @x 仅保留 ab。 没有足够的空间来保留增补字符。

DECLARE @x AS NVARCHAR (10) = 'ab' + NCHAR(0x10000);

SELECT CAST (@x AS NVARCHAR (3));

在使用 SC 排序规则时,CONVERT 行为类似于 CAST。 有关详细信息,请参阅排序规则和 Unicode 支持 - 补充字符。

兼容性支持

在早期版本的SQL Server中,对于CONVERT时间和datetime2数据类型和操作的默认样式CAST为121,除非在计算列表达式中使用任一类型。 对于计算列,默认样式为 0。 这种行为会影响计算列的创建、用于自动参数化查询或约束定义时。

在兼容性级别110及以上CAST,时间和日期时间2数据类型的和CONVERT操作总是默认121样式。 如果查询依赖旧行为,使用小于 110的兼容性级别,或在受影响查询中明确指定 0 样式。

兼容性级别值 默认样式和 CASTCONVERT1 计算列的默认样式
< 110 121 0
>= 110 121 121

1 计算列除外

将数据库升级到兼容性 110 及以上水平不会改变存储在磁盘上的用户数据。 您必须相应手动更正此数据。 例如,如果你用 SELECT INTO 包含上述计算列表达式的源创建表,数据(使用样式 0)会被存储,而不是计算出的列定义本身。 你必须手动更新这些数据以匹配样式 121。

示例

本文中的代码示例使用 AdventureWorks2025、AdventureWorksDW2025 或 AdventureWorksLT2025 示例数据库,您可以从 Azure Data SQL Samples Repository GitHub 存储库下载这些数据库。

答: 同时使用 CAST 和 CONVERT

每个示例检索标价的第一位是 3 的产品的名称,并将其 ListPrice 值转换为 int。

使用 CAST:

USE AdventureWorks2025;
GO

SELECT SUBSTRING(Name, 1, 30) AS ProductName,
       ListPrice
FROM Production.Product
WHERE CAST (ListPrice AS INT) LIKE '33%';
GO

使用 CONVERT:

USE AdventureWorks2025;
GO

SELECT SUBSTRING(Name, 1, 30) AS ProductName,
       ListPrice
FROM Production.Product
WHERE CONVERT (INT, ListPrice) LIKE '33%';
GO

结果集如下。 CAST 和 CONVERT 的示例结果集相同。

ProductName                    ListPrice
------------------------------ ---------------------
LL Road Frame - Black, 58      337.22
LL Road Frame - Black, 60      337.22
LL Road Frame - Black, 62      337.22
LL Road Frame - Red, 44        337.22
LL Road Frame - Red, 48        337.22
LL Road Frame - Red, 52        337.22
LL Road Frame - Red, 58        337.22
LL Road Frame - Red, 60        337.22
LL Road Frame - Red, 62        337.22
LL Road Frame - Black, 44      337.22
LL Road Frame - Black, 48      337.22
LL Road Frame - Black, 52      337.22
Mountain-100 Black, 38         3374.99
Mountain-100 Black, 42         3374.99
Mountain-100 Black, 44         3374.99
Mountain-100 Black, 48         3374.99
HL Road Front Wheel            330.06
LL Touring Frame - Yellow, 62  333.42
LL Touring Frame - Blue, 50    333.42
LL Touring Frame - Blue, 54    333.42
LL Touring Frame - Blue, 58    333.42
LL Touring Frame - Blue, 62    333.42
LL Touring Frame - Yellow, 44  333.42
LL Touring Frame - Yellow, 50  333.42
LL Touring Frame - Yellow, 54  333.42
LL Touring Frame - Yellow, 58  333.42
LL Touring Frame - Blue, 44    333.42
HL Road Tire                   32.60

B. 将 CAST 与算术运算符结合使用

此示例将本年度截止到现在的全部销售额 (Computed) 除以佣金百分比 (SalesYTD),从而得出单列计算结果 (CommissionPCT)。 此值舍入为最接近的整数,然后 CAST 为 int 数据类型。

USE AdventureWorks2025;
GO

SELECT CAST (ROUND(SalesYTD / CommissionPCT, 0) AS INT) AS Computed
FROM Sales.SalesPerson
WHERE CommissionPCT != 0;
GO

结果集如下。

Computed
------
379753754
346698349
257144242
176493899
281101272
0
301872549
212623750
298948202
250784119
239246890
101664220
124511336
97688107

°C 使用 CAST 进行连接

此示例使用 CAST 连接非字符型表达式。 它使用 AdventureWorksDW2025 数据库。

SELECT 'The list price is ' + CAST (ListPrice AS VARCHAR (12)) AS ListPrice
FROM dbo.DimProduct
WHERE ListPrice BETWEEN 350.00 AND 400.00;

结果集如下。

ListPrice
------------------------
The list price is 357.06
The list price is 364.09
The list price is 364.09
The list price is 364.09
The list price is 364.09

D. 使用 CAST 生成可读性更高的文本

这个例子在SELECT列表中使用 CAST 了将列转换为 Namechar(10) 列。 它使用 AdventureWorksDW2025 数据库。

SELECT DISTINCT CAST (EnglishProductName AS CHAR (10)) AS Name,
                ListPrice
FROM dbo.DimProduct
WHERE EnglishProductName LIKE 'Long-Sleeve Logo Jersey, M';
GO

结果集如下。

Name        ListPrice
----------  ---------
Long-Sleev  31.2437
Long-Sleev  32.4935
Long-Sleev  49.99

E. 将 CAST 与 LIKE 子句结合使用

此示例将 money 列 SalesYTD 值转换为数据类型 int,然后转换为数据类型 char(20),以便 子句可以使用。

USE AdventureWorks2025;
GO

SELECT p.FirstName,
       p.LastName,
       s.SalesYTD,
       s.BusinessEntityID
FROM Person.Person AS p
     INNER JOIN Sales.SalesPerson AS s
         ON p.BusinessEntityID = s.BusinessEntityID
WHERE CAST (CAST (s.SalesYTD AS INT) AS CHAR (20)) LIKE '2%';
GO

结果集如下。

FirstName        LastName            SalesYTD         BusinessEntityID
---------------- ------------------- ---------------- -------------
Tsvi             Reiter              2811012.7151      279
Syed             Abbas               219088.8836       288
Rachel           Valdez              2241204.0424      289

F. 使用 CONVERT 或 CAST 转换为类型化的 XML

这些示例展示了如何利用 将CONVERT数据转换为类型化 XML,方法是使用 xml 数据类型和列(SQL Server)。

此示例将包含空格、文本和标记的字符串转换为类型化的 XML,并删除所有无用空格(节点之间的边界空格):

SELECT CONVERT (XML, '<root><child/></root>');

此示例将包含空格、文本和标记的类似字符串转换为类型化的 XML,并保留无用空格(节点之间的边界空格):

SELECT CONVERT (XML, '<root>          <child/>         </root>', 1);

此示例将包含空格、文本和标记的字符串转换为类型化的 XML:

SELECT CAST ('<Name><FName>Carol</FName><LName>Elliot</LName></Name>' AS XML);

更多示例请参见 “创建XML数据实例 ”。

G. 对 datetime 数据使用 CAST 和 CONVERT

从 GETDATE() 值开始,此示例显示当前日期和时间,使用 CAST 将当前日期和时间更改为字符数据类型,然后使用 CONVERT 以 ISO 8601 格式显示日期和时间。

SELECT GETDATE() AS UnconvertedDateTime,
       CAST (GETDATE() AS NVARCHAR (30)) AS UsingCast,
       CONVERT (NVARCHAR (30), GETDATE(), 126) AS UsingConvertTo_ISO8601;
GO

结果集如下。

UnconvertedDateTime     UsingCast              UsingConvertTo_ISO8601
----------------------- ---------------------- ------------------------------
2022-04-18 09:58:04.570 Apr 18 2022  9:58AM    2022-04-18T09:58:04.570

此示例与上述示例几乎完全相反。 该示例将日期和时间显示为字符数据,使用 CAST 将字符数据更改为 datetime 数据类型,然后使用 将字符数据更改为 datetime 数据类型。

SELECT '2006-04-25T15:50:59.997' AS UnconvertedText,
       CAST ('2006-04-25T15:50:59.997' AS DATETIME) AS UsingCast,
       CONVERT (DATETIME, '2006-04-25T15:50:59.997', 126) AS UsingConvertFrom_ISO8601;
GO

结果集如下。

UnconvertedText         UsingCast               UsingConvertFrom_ISO8601
----------------------- ----------------------- ------------------------
2006-04-25T15:50:59.997 2006-04-25 15:50:59.997 2006-04-25 15:50:59.997

H. 使用 CONVERT 处理二进制和字符数据

这些示例使用不同样式显示二进制和字符数据转换的结果。

--Convert the binary value 0x4E616d65 to a character value.
SELECT CONVERT (CHAR (8), 0x4E616d65, 0) AS [Style 0, binary to character];

结果集如下。

Style 0, binary to character
----------------------------
Name

这个例子表明样式 1 可以强制结果截断。 结果集中的字符 0x 强制截断。

SELECT CONVERT (CHAR (8), 0x4E616d65, 1) AS [Style 1, binary to character];

结果集如下。

Style 1, binary to character
------------------------------
0x4E616D

这个例子表明样式 2 不会截断结果,因为结果中没有包含字符 0x。

SELECT CONVERT (CHAR (8), 0x4E616d65, 2) AS [Style 2, binary to character];

结果集如下。

Style 2, binary to character
------------------------------
4E616D65

将字符值 Name 转换为二进制值。

SELECT CONVERT (BINARY (8), 'Name', 0) AS [Style 0, character to binary];

结果集如下。

Style 0, character to binary
----------------------------
0x4E616D6500000000
SELECT CONVERT (BINARY (4), '0x4E616D65', 1) AS [Style 1, character to binary];

结果集如下。

Style 1, character to binary
----------------------------
0x4E616D65
SELECT CONVERT (BINARY (4), '4E616D65', 2) AS [Style 2, character to binary];

结果集如下。

Style 2, character to binary
----------------------------------
0x4E616D65

一。 转换日期和时间数据类型

此示例显示了 date、time 及 datetime 数据类型的转换。

DECLARE @d1 AS DATE,
        @t1 AS TIME,
        @dt1 AS DATETIME;

SET @d1 = GETDATE();
SET @t1 = GETDATE();
SET @dt1 = GETDATE();
SET @d1 = GETDATE();

-- When converting date to datetime the minutes portion becomes zero.
SELECT @d1 AS DATE,
       CAST (@d1 AS DATETIME) AS [date as datetime];

-- When converting time to datetime the date portion becomes zero
-- which converts to January 1, 1900.
SELECT @t1 AS TIME,
       CAST (@t1 AS DATETIME) AS [time as datetime];

-- When converting datetime to date or time non-applicable portion is dropped.
SELECT @dt1 AS DATETIME,
       CAST (@dt1 AS DATE) AS [datetime as date],
       CAST (@dt1 AS TIME) AS [datetime as time];

考虑从 date 转换到 datetime 或 datetime2 时,请确保这些值在兼容的范围内。 datetime 的最小年份值为 ,而 date 和 datetime2 的最小年份值为 1753。

DECLARE @d1 AS DATE,
        @dt1 AS DATETIME,
        @dt2 AS DATETIME2;

SET @d1 = '1492-08-03';
--This is okay; Minimum YYYY for DATE is 0001

SET @dt2 = CAST (@d1 AS DATETIME2);
--This is okay; Minimum YYYY for DATETIME2 IS 0001

SET @dt1 = CAST (@d1 AS DATETIME);
--This returns an error with (Msg 242) "The conversion of a date data type to a datetime data type resulted in an out-of-range value."
--Minimum YYYY for DATETIME is 1753

J. 使用 CONVERT 处理不同格式的 datetime 数据

从 GETDATE() 值开始,此示例使用CONVERT 显示本文日期和时间样式部分的所有日期和时间样式。

格式编号 示例查询 示例结果
0 SELECT CONVERT(NVARCHAR, GETDATE(), 0) 2019 年 8 月 23 日下午 1:39
1 SELECT CONVERT(NVARCHAR, GETDATE(), 1) 08/23/19
2 SELECT CONVERT(NVARCHAR, GETDATE(), 2) 19.08.23
3 SELECT CONVERT(NVARCHAR, GETDATE(), 3) 23/08/19
4 SELECT CONVERT(NVARCHAR, GETDATE(), 4) 23.08.19
5 SELECT CONVERT(NVARCHAR, GETDATE(), 5) 23-08-19
6 SELECT CONVERT(NVARCHAR, GETDATE(), 6) 8 月 19 日 23 日
7 SELECT CONVERT(NVARCHAR, GETDATE(), 7) 8 月 23 日,19 日
8 或 24 或 108 SELECT CONVERT(NVARCHAR, GETDATE(), 8) 13:39:17
9 或 109 SELECT CONVERT(NVARCHAR, GETDATE(), 9) 2019 年 8 月 23 日下午 1:39:17:090
10 SELECT CONVERT(NVARCHAR, GETDATE(), 10) 08-23-19
11 SELECT CONVERT(NVARCHAR, GETDATE(), 11) 19/08/23
12 SELECT CONVERT(NVARCHAR, GETDATE(), 12) 190823
13 或 113 SELECT CONVERT(NVARCHAR, GETDATE(), 13) 2019年8月23日 13:39:17:090
14 或 114 SELECT CONVERT(NVARCHAR, GETDATE(), 14) 13:39:17:090
20 或 120 SELECT CONVERT(NVARCHAR, GETDATE(), 20) 2019-08-23 13:39:17
21 或 25 或 121 SELECT CONVERT(NVARCHAR, GETDATE(), 21) 2019-08-23 13:39:17.090
22 SELECT CONVERT(NVARCHAR, GETDATE(), 22) 08/23/19 1:39:17 PM
23 SELECT CONVERT(NVARCHAR, GETDATE(), 23) 2019-08-23
101 SELECT CONVERT(NVARCHAR, GETDATE(), 101) 08/23/2019
102 SELECT CONVERT(NVARCHAR, GETDATE(), 102) 2019.08.23
103 SELECT CONVERT(NVARCHAR, GETDATE(), 103) 23/08/2019
104 SELECT CONVERT(NVARCHAR, GETDATE(), 104) 23.08.2019
105 SELECT CONVERT(NVARCHAR, GETDATE(), 105) 23-08-2019
106 SELECT CONVERT(NVARCHAR, GETDATE(), 106) 2019 年 8 月 23 日
107 SELECT CONVERT(NVARCHAR, GETDATE(), 107) 2019 年 8 月 23 日
110 SELECT CONVERT(NVARCHAR, GETDATE(), 110) 08-23-2019
111 SELECT CONVERT(NVARCHAR, GETDATE(), 111) 2019/08/23
112 SELECT CONVERT(NVARCHAR, GETDATE(), 112) 20190823
113 SELECT CONVERT(NVARCHAR, GETDATE(), 113) 2019年8月23日 13:39:17.090
120 SELECT CONVERT(NVARCHAR, GETDATE(), 120) 2019-08-23 13:39:17
121 SELECT CONVERT(NVARCHAR, GETDATE(), 121) 2019-08-23 13:39:17.090
126 SELECT CONVERT(NVARCHAR, GETDATE(), 126) 2019-08-23T13:39:17.09
127 SELECT CONVERT(NVARCHAR, GETDATE(), 127) 2019-08-23T13:39:17.09
130 SELECT CONVERT(NVARCHAR, GETDATE(), 130) 22 ذو الحجة 1440 1:39:17.090P
131 SELECT CONVERT(NVARCHAR, GETDATE(), 131) 22/12/1440 1:39:17.090PM

K. 允许的转换中数据类型优先级的影响

以下示例定义一个类型为 varchar(10) 的变量,将整数值赋给该变量,然后选择该变量与字符串的串联。

DECLARE @string AS VARCHAR (10);
SET @string = 1;

SELECT @string + ' is a string.' AS Result;

结果集如下。

Result
-----------------------
1 is a string.

int 值 1 已转换为 varchar。

此示例显示了一个类似的查询,但它使用的是 int 变量:

DECLARE @notastring AS INT;
SET @notastring = '1';

SELECT @notastring + ' is not a string.' AS Result;

在此例中,SELECT 语句会引发以下错误:

Msg 245, Level 16, State 1, Line 3
Conversion failed when converting the varchar value ' is not a string.' to data type int.

为了评估表达@notastring + ' is not a string.'式 ,数据库引擎 需要遵循数据类型优先规则,完成隐式转换,然后才能计算表达式的结果。 由于整数优先级高于varchar,Database Engine尝试将字符串转换为整数,但失败了,因为该字符串无法转换为整数。

如果我们给出一个可转换的字符串,该语句成功,如下例所示:

DECLARE @notastring AS INT;
SET @notastring = '1';

SELECT @notastring + '1';

在此例中,字符串 '1' 可以转换为整数值 1,因而此 SELECT 语句会返回值 2。 当所提供的数据类型为整数时,算 + 子变成了加法数学算子,而不是字符串串接。

示例:Azure Synapse Analytics

L. 使用 CAST 和 CONVERT

此示例检索标价的第一位是 3 的产品的名称,并将这些产品的 ListPrice 转换为 int。它使用 数据库。

SELECT EnglishProductName AS ProductName,
       ListPrice
FROM dbo.DimProduct
WHERE CAST (ListPrice AS INT) LIKE '3%';

此示例显示使用 CONVERT 而不是 CAST 的相同查询。 它使用 AdventureWorksDW2025 数据库。

SELECT EnglishProductName AS ProductName,
       ListPrice
FROM dbo.DimProduct
WHERE CONVERT (INT, ListPrice) LIKE '3%';

M. 将 CAST 与算术运算符结合使用

此例通过产品单价 (UnitPrice) 除以折扣率 (UnitPriceDiscountPct) 计算单列值。 然后,此结果会舍入到最接近的整数,并最终转换为 int 数据类型。 此示例使用 AdventureWorksDW2025 数据库。

SELECT ProductKey,
       UnitPrice,
       UnitPriceDiscountPct,
       CAST (ROUND(UnitPrice * UnitPriceDiscountPct, 0) AS INT) AS DiscountPrice
FROM dbo.FactResellerSales
WHERE SalesOrderNumber = 'SO47355'
      AND UnitPriceDiscountPct > .02;

结果集如下。

ProductKey  UnitPrice  UnitPriceDiscountPct  DiscountPrice
----------  ---------  --------------------  -------------
323         430.6445   0.05                  22
213         18.5043    0.05                  1
456         37.4950    0.10                  4
456         37.4950    0.10                  4
216         18.5043    0.05                  1

N. 将 CAST 与 LIKE 子句结合使用

本例将 货币 列 ListPrice 转换为 int 类型,然后转换为 char(20) 类型,使 LIKE 子句能够使用该类型。 此示例使用 AdventureWorksDW2025 数据库。

SELECT EnglishProductName AS Name,
       ListPrice
FROM dbo.DimProduct
WHERE CAST (CAST (ListPrice AS INT) AS CHAR (20)) LIKE '2%';

O. 对 datetime 数据使用 CAST 和 CONVERT

此示例显示当前日期和时间,使用 CAST 将当前日期和时间更改为字符数据类型,最终使用 CONVERT 以 ISO 8601 格式显示日期和时间。 此示例使用 AdventureWorksDW2025 数据库。

SELECT TOP (1) SYSDATETIME() AS UnconvertedDateTime,
               CAST (SYSDATETIME() AS NVARCHAR (30)) AS UsingCast,
               CONVERT (NVARCHAR (30), SYSDATETIME(), 126) AS UsingConvertTo_ISO8601
FROM dbo.DimCustomer;

结果集如下。

UnconvertedDateTime     UsingCast                     UsingConvertTo_ISO8601
---------------------   ---------------------------   ---------------------------
07/20/2010 1:44:31 PM   2010-07-20 13:44:31.5879025   2010-07-20T13:44:31.5879025

此示例与上述示例大致相反。 该示例将日期和时间显示为字符数据,使用 CAST 将字符数据更改为 datetime 数据类型,然后使用 将字符数据更改为 datetime 数据类型。 此示例使用 AdventureWorksDW2025 数据库。

SELECT TOP (1) '2010-07-25T13:50:38.544' AS UnconvertedText,
               CAST ('2010-07-25T13:50:38.544' AS DATETIME) AS UsingCast,
               CONVERT (DATETIME, '2010-07-25T13:50:38.544', 126) AS UsingConvertFrom_ISO8601
FROM dbo.DimCustomer;

结果集如下。

UnconvertedText         UsingCast               UsingConvertFrom_ISO8601
----------------------- ----------------------- ------------------------
2010-07-25T13:50:38.544 07/25/2010 1:50:38 PM   07/25/2010 1:50:38 PM