4.1 SQL Server数据类型详解

SQL Server数据类型详解

摘要:通过本文,你将简单了解 SQLServer 数据类型,包括数字、字符串、二进制字符串、日期和时间以及其他数据类型。

SQL Server数据类型预览

在SQL Server中,列、变量和参数跟高级语言的变量一样,都有自己的数据类型。数据类型是指定这些对象可以存储的数据类型的属性。数据类型可以是整数,字符串,货币,日期和时间等类型。

SQL Server提供了一个数据类型的列表,该列表定义了可以使用的所有类型数据,例如定义列或声明变量。

下图说明了SQL Server数据类型系统:

注意,SQLServer 将在其未来版本中删除 ntext、 text 和 image 数据类型。因此,应该避免使用这些数据类型,而是使用 nvarchar (max)、 varchar (max)和 varbinar (max)数据类型。

精确的数据类型

精确数据类型存储精确数字,例如整数、小数或货币金额。

  • bit类型存储0、1或者NULL。
  • int, bigint, smallint和tinyint存储整形数据。
  • decimal和numeric数据类型存储具有固定精度和比例的数字,值得注意的是decimal和numeric是同义词。
  • money和smallmoney数据类型存储货币值

下表说明了精确数据类型的特点:

数据类型 最小 最大 内存 描述
bigint -2^63(−9,223,372,036,854,775,808) 2^63−1 (−9,223,372, 036,854,775,807) 8字节
int −2^31(−2,147,483,648) 2^31−1(−2,147,483,647) 4字节
smallint −2^15(−32,767) 2^15(−32,768) 2字节
tinyint 0 255 1字节
bit 0 1 1位
decimal −10^38+1 10^381−1 5到17字节
numeric −10^38+1 10^381−1 5到17字节
money −922,337,203,685,477.5808 +922,337, 203, 685,477.5807 8字节
smallmoney −214,478.3648 +214,478.3647 4字节

近似数据类型

近似数字数据类型存储浮点数字数据。它们通常用于科学计算中,通常不建议使用,因为算术运算会导致精度损失。

数据类型 最小 最大 内存 精度
float(n)/双精度 −1.79E+308 1.79E+308 取决于n的值 7位数
real/单精度 −3.40E+38 3.40E+38 4字节 15位数

日期和时间数据类型

日期和时间数据类型存储日期数据和时间数据,以及日期时间偏移量。

数据类型 最小 最大 内存 精度
datetime 1753-01-01 9999-12-31 8字节 四舍五入到0.000.003.007的增量
smalldatetime 1900-01-01 2079-06-06 固定4字节 1分钟
date 0001-01-01 9999-12-31 固定3字节 1天
time 00:00:00.0000000 23:59:59.9999999 5字节 100纳秒
datetimeoffset 0001-01-01 9999-12-31 10字节 100纳秒
datetime2 0001-01-01 9999-12-31 6字节 100纳秒

注意:如果开发新的应用程序,则应使用 time、 date、 datetime2和 datetimeoffest 数据类型。因为这些类型符合 SQL 标准,并且更具可移植性。此外,time、 datetime2和 datetimeoffest 具有更高的秒精度,并且 datetimeoffest 支持时区。

字符串数据类型

字符串数据类型允许存储固定长度(char)或可变长度数据(varchar)。文本数据类型可以在服务器的代码页中存储非 Unicode 数据。

数据类型 最小 最大 内存
char 0个字符 8000个字符 n字节
varchar 0个字符 8000个字符 n字节+2字节
varchar(max) 0个字符 2^31(2,147,483,648)个字符 n字节+2字节
text 0个字符 2^31-1(2,147,483,648)个字符 n字节+4字节

Unicode字符串数据类型

数据类型 最小 最大 内存
nchar 0字符 4000字符 2*n字节
nvarchar 0字符 4000字符 2*n字节 + 2字节
ntext 0字符 1,073,741,823字符 2*字符串长度

二进制字符串数据类型

数据类型 最小 最大 内存
binary 0字节 8000字节 n字节
varbinary 0字节 8000字节 实际数据长度 + 2 bytes
image 0字节 2,147,483,647字节 实际数据长度

其他数据类型

数据类型 描述
cursor 对于包含对游标引用的变量或存储过程output参数
rowversion 在数据库中自动生成的独一无二的二进制数。
hierarchyid 表示树层次结构中的树位置
uniqueidentifier 16-byte GUID
sql_variant 存储其他数据类型的值
XML 将XML数据存储在列中,或XML类型的变量
Spatial Geometry type(空间几何类型) 在平坐标系中表示数据
Spatial Geography type(空间地理类型) 存储椭球(圆形地球)数据,例如GPS纬度和经度坐标
table 暂时存储结果集以供以后处理

上面只是简单概述了SQL Server的数据类型,后续会详细研究每种数据类型。

INT

SQLServer 支持标准的 SQL 整数类型,包括 BIGINT、 INT、 SMALLINT 和 TINYINT。下表说明了每种整数类型的范围和存储:

数据类型 范围 存储
BIGINT -263 (-9,223,372,036,854,775,808) 到 263-1 (9,223,372,036,854,775,807) 8 Bytes
INT -231 (-2,147,483,648) 到 231-1 (2,147,483,647) 4 Bytes
SMALLINT -215 (-32,768) 到 215-1 (32,767) 2 Bytes
TINYINT 0to 255 1 Byte

使用能够可靠地包含所有可能值的最小整数数据类型是一个很好的实践。例如,要在一个家庭中存储孩子的数量,TINYINT 就足够了,因为现在没有人可以生育超过255个孩子。然而,TINYINT 不足以存储一座建筑的楼层,因为一座建筑可以有超过255层。

下面的语句创建一个由四个整数列组成的新表:

CREATE TABLE dbo.sql_server_integers (
	bigint_col bigint,
	int_col INT,
	smallint_col SMALLINT,
	tinyint_col tinyint
);
INSERT INTO dbo.sql_server_integers (
	bigint_col,
	int_col,
	smallint_col,
	tinyint_col
)
VALUES
(
    9223372036854775807,
    2147483647,
    32767,
    255
);

要显示 dbo.sql_server_Integrgers表中存储的值,可以使用以下SELECT语句:

SELECT
	bigint_col,
	int_col,
	smallint_col,
	tinyint_col
FROM
	dbo.sql_server_integers;

转换整数数据

SQLServer将大于2,147,483,647的整数常量转换为DECIMAL(十进制)数据类型,而不是下面示例中所示的BIGINT数据类型(如下图r2):

SELECT 2147483647 / 3 AS r1, 
	   2147483649 / 3 AS r2;

Decimal

SQLServer DECIMAL数据类型概述

若要存储具有固定精度和比例的数字,请使用DECIMAL数据类型。
下面显示了DECIMAL数据类型的语法:

DECIMAL(p,s)

在这个句法中:

  • p是精度,它是将存储在小数点的左侧和右侧的最大十进制数字总数。精度的范围从1到38。默认精度为38。
  • s是小数点右侧存储的小数位数。刻度的范围为0到p(精度)。只有指定了精度p,才能指定比例。默认情况下,s为零。
  • 比如1.0234,那么p就是5,s是4

最大占用存储大小取决于下表所示的精度:

精度 存储大小(bytes)
1-9 5
10-19 9
20-28 13
29-38 17

在SQL Server中NUMERIC和DECIMAL是同义词,只有细微可忽略的差别,因此可以互换地使用它们。
下列声明是等效的:

DECIMAL(10,2)
NUMERIC(10,2)

因为在国际化标准组织(ISO)规定中,DECIMAL和DEC是同义词,所以写DECIMAL或DEC是一样的:

DECIMAL(10,2)
DEC(10,2)

SQL Server DECIMAL例子

首先,创建一个由两列组成的新表: 一个DECIMAL和一个NUMERIC:

CREATE TABLE dbo.sql_server_decimal (
    dec_col DECIMAL (4, 2),
    num_col NUMERIC (4, 2)
);

然后插入数据

INSERT INTO dbo.sql_server_decimal (dec_col, num_col)
VALUES
    (10.05, 20.05);

查询数据

SELECT
    dec_col,
    num_col
FROM
    dbo.sql_server_decimal;

最后尝试向表中插入一个新行,其值超过列定义中指定的精度和小数位数:

INSERT INTO dbo.sql_server_decimal (dec_col, num_col)
VALUES
    (99.999, 12.345);

SQLServer报如下错误并终止语句:

Arithmetic overflow error converting numeric to data type numeric.
The statement has been terminated

BIT

BIT数据类型概述

SQLServer BIT数据类型是一个整数数据类型,可以是0、1或NULL值。

SQL Server优化了BIT列的存储。如果表具有8个或更少的BIT列,则SQL Server将它们存储为1个byte(8bit)。如果表具有9个到16个bit的列,则SQL Server将它们存储为2个byte,依此类推。

SQL Server将字符串值TRUE转换为1,FALSE转换为0。它还将任何非零值转换为1。

SQL Server BIT例子

下面的语句创建一个包含一个 BIT 列的新表:

CREATE TABLE dbo.sql_server_bit (
    bit_col BIT
);

将bit值1插入bit列:

INSERT INTO dbo.sql_server_bit (bit_col)
OUTPUT inserted.bit_col
VALUES(1);

输出:

bit_col
-------
1

(1 row affected)

插入值0:

INSERT INTO dbo.sql_server_bit (bit_col)
OUTPUT inserted.bit_col
VALUES(0);

输出:

bit_col
-------
0

(1 row affected)

如果将字符串值True插入bit列,SQL server会将其转换为位1:

INSERT INTO dbo.sql_server_bit (bit_col)
OUTPUT inserted.bit_col
VALUES('True');

输出:

bit_col
-------
1

(1 row affected)

同样,SQL Server将false的字符串值转换为位0:

INSERT INTO dbo.sql_server_bit (bit_col)
OUTPUT inserted.bit_col
VALUES('False');

输出:

bit_col
-------
0

(1 row affected)

SQLServer 将任何非零值转换为位1。例如:

INSERT INTO dbo.sql_server_bit (bit_col)
OUTPUT inserted.bit_col
VALUES(0.5);

输出:

bit_col
-------
1

(1 row affected)

CHAR

SQL Server CHAR数据类型概述

如果要存储固定的长度,非Unicode字符串数据,则使用SQL Server Char数据类型:

CHAR(n)

在此语中,n指定字符串长度从1到8,000。

因为 n 是可选的,如果不在数据定义或变量声明语句中指定它,它的默认值是1。

只有当列中的值的大小固定时,才应该使用 CHAR 数据类型。

将字符串值插入CHAR列时。如果字符串值的长度小于列中指定的长度,则 SQLServer 将会在此字符串后面使用空格来补齐,但是,当SELECT此字符串值时,SQLServer 会在返回该字符串值之前删除尾随空格。

另一方面,如果插入长度超过列长度的值,SQLServer 将会报错。

ISO标准规定char和character是同义词,所以可以互换使用,如下等价:

char(10)
character(10)

SQL Server Char数据类型示例

下面的语句创建一个包含 CHAR 列的新表:

CREATE TABLE dbo.sql_server_char (
    val CHAR(3)
);

请注意,如果您在数据库中没有test架构,则可以在创建SQL_SERVER_CHAR表格之前使用以下语句来创建它:

CREATE SCHEMA test; 
GO

将一个固定长度的字符串插入 CHAR 列:

INSERT INTO dbo.sql_server_char (val)
VALUES
    ('ABC');

如果尝试插入一个长度超过CHAR列指定的长度3的话就会报错:

INSERT INTO dbo.sql_server_char (val)
VALUES
    ('XYZ1');

SQL Server报如下错误:

String or binary data would be truncated.--字符串被截断了
The statement has been terminated.--语句被终止

以下语句将单个字符插入 dbo.sql_server_char 表的 val 列:

INSERT INTO dbo.sql_server_char (val)
VALUES
    ('A');

在 SQLServer 中,LEN 函数返回指定列中不包含尾随空格的字符数,而 DATALENGTH 函数返回字节数。

请看如下语句:

SELECT
    val,
    LEN(val) len,
    DATALENGTH(val) data_length
FROM
    sql_server_char;

即使字符"A"只是一个字符,但列所占字节数为固定为三个字符。

NCHAR

SQL Server NCHAR数据类型概述

要在数据库中存储固定长度的 Unicode字符字符串数据,可以使用 SQL Server NCHAR 数据类型:

NCHAR(n)

在此语法中,n指定字符串长度从1到4,000。NCHAR值的存储大小为两倍n字节。

ISO(国际标准化组织)规定了NCHAR和NATIONAL CHAR是同义词,因此可以相互替换使用。如下等价:

NCHAR(10)
NATIONAL CHAR(10)

与CHAR数据类型类似,NCHAR仅用于存储固定长度的字符串。如果数据值的长度是可变的,则应考虑使用VARCHAR或NVARCHAR数据类型。

CHAR和NCHAR

下面是 CHAR 和 NCHAR 数据类型之间的主要区别:

CHAR NCHAR
仅存储非 Unicode 字符。 以Unicode UCS-2字符的形式存储Unicode字符。
需要1个字节来存储一个字符 需要2个字节来存储一个字符。
存储大小等于列定义或变量声明中指定的大小。 存储大小等于列定义或变量声明中指定的大小的两倍。
最多可存储8000个字符。 最多可存储4000个字符。

SQL Server NCHAR示例

创建一个包含一个 NCHAR 列的新表:

CREATE TABLE dbo.sql_server_nchar (
    val NCHAR(1) NOT NULL
);

以下插入语句插入日语格式字符a(あ):

INSERT INTO dbo.sql_server_nchar (val)
VALUES
    (N'あ');

注意:Unicode字符串必须加上前缀N,如:N'你是个好人',否则SQL Server可能无法识别某些Unicode字符

跟CHAR一样,如果插入的字符串的长度大于列定义中指定的长度,则 SQLServer 将会报错。
比如,如下语句插入两个字符的到dbo.sql_server_nchar表的val列(NCHAR(1)):

INSERT INTO dbo.sql_server_nchar (val)
VALUES
    (N'你好'); 

SQL Server报如下错误:

String or binary data would be truncated.--字符串被截断了
The statement has been terminated.--语句被终止

要知道 val 列的字符数和字节数,可以使用 LENDATALENGTH 函数,如下所示:

SELECT
    val,
    len(val) length,
    DATALENGTH(val) data_length
FROM
    dbo.sql_server_nchar;

VARCHAR

SQL Server VARCHAR数据类型概述

SQL Server VARCHAR数据类型用于存储可变长度的非Unicode字符串数据。用法如下:

VARCHAR(n)

在此语法中,n是最大可以存储的非Unicode字符个数,n 定义范围为1到8,000的字符串长度。如果不指定 n,则其默认值为1。

声明varchar列的另一种方法是使用以下语法:

VARCHAR(max)

在此语法中,Max定义最大存储大小为\(2^{31}\)-1字节(2 GB)。

一般来说,VARCHAR 值的存储大小是所存储的数据的实际长度加上2个字节。

ISO(国际标准化组织)规定了VARCHAR,CHARVARYINGCHARACTERVARYING是同义词,因此可以相互替换使用。如下等价:

VARCHAR(10)
CHARVARYING(10)
CHARACTERVARYING(10)

SQL Server VARCHAR例子

下面的语句创建一个包含一个 VARCHAR 列的新表:

CREATE TABLE dbo.sql_server_varchar (
    val VARCHAR NOT NULL
);

因为没有指定 val列的字符串长度,所以它默认为1。
若要更改 val 列的字符串长度,请使用 ALTER TABLE ALTER COLUMN 语句:

ALTER TABLE dbo.sql_server_varchar 
ALTER COLUMN val VARCHAR (10) NOT NULL;

以下语句将一个新字符串插入 dbo.sql_server_varchar 表的 val 列:

INSERT INTO dbo.sql_server_varchar (val)
VALUES
    ('SQL Server');

该语句正常执行,因为字符串值的长度等于列定义中定义的长度10。

下面的语句尝试插入新的字符串数据,其长度大于列的字符串长度:

INSERT INTO dbo.sql_server_varchar (val)
VALUES
    ('SQL Server VARCHAR');

SQLServer 报错并终止语句:

String or binary data would be truncated.--字符串被截断了
The statement has been terminated.--语句被终止

要知道 VARCHAR 列中存储的字符数和字节数,可以使用 LENDATALENGTH 函数,如下面的查询所示:

SELECT
    val,
    LEN(val) len,
    DATALENGTH(val) data_length
FROM
    dbo.sql_server_varchar;

NVARCHAR

SQL Server NVARCHAR数据类型概述

SQLServerNVARCHAR 数据类型用于存储可变长度的 Unicode 字符串数据:

NVARCHAR(n)

在此语法中,n定义最大可以存储的字符个数,n 定义范围为1到4,000的字符串长度。如果不指定字符串长度,则其默认值为1。

声明 NVARCHAR 列的另一种方法是使用以下语法:

NVARCHAR(MAX)

在此语法中,Max定义最大存储大小为\(2^{31}\)-1字节(2 GB)。

一般来说,NVARCHAR 值的实际存储大小(以字节为单位)是输入字符数的两倍再加上2个字节。

ISO标准中,NVARCHARNATIONAL CHAR VARYINGNATIONAL CHARACTER VARYING等价,可以互换使用:

NVARCHAR(10)
NATIONAL CHAR VARYING(10)
NATIONAL CHARACTER VARYING(10)

VARCHAR和NVARCHAR

下表说明了 VARCHAR 和 NVARCHAR 数据类型之间的主要区别:

VARCHAR NVARCHAR
字符数据类型 可变长度的非 Unicode 字符 可变长度,包括 Unicode 和非 Unicode 字符,如日文、韩文和中文。
最大长度 最多8,000个字符 最多4,000个字符
字符大小 每个字符占用1个字节 每个Unicode/非Unicode字符占用2个字节
存储大小 实际字符串长度(字节) 2倍实际字符串长度(字节)
使用 当数据长度为可变或可变长度列,并且实际数据总是小于容量时使用 由于仅用于存储,所以只在有Unicode字符时使用,如日文汉字或韩文汉字。

SQLServer NVARCHAR示例

下面的语句创建一个包含一个NVARCHAR列的新表:

CREATE TABLE dbo.sql_server_nvarchar (
    val NVARCHAR NOT NULL
);

在此示例中,NVARCHAR 列的字符串长度默认为1。
若要更改 val 列的字符串长度,请使用 ALTER TABLE ALTER COLUMN 语句:

ALTER TABLE dbo.sql_server_Nvarchar 
ALTER COLUMN val NVARCHAR (10) NOT NULL;

以下语句将一个新字符串插入 dbo.sql_server_nvarchar 表的 val 列:

INSERT INTO dbo.sql_server_varchar (val)
VALUES
    (N'你是个好人');

语句正常执行,因为字符串值的长度(5)小于列定义中定义的字符串长度(10)。

下面的语句尝试插入一个长度大于 val 列的字符串长度的新字符串数据:

INSERT INTO dbo.sql_server_nvarchar (val)
VALUES
    (N'你是个好人,你是个好人,你是个好人');

SQLServer 报错并终止语句:

String or binary data would be truncated.--字符串被截断了
The statement has been terminated.--语句被终止

想知道存储在NVARCHAR列中的值的字符数和以字节为单位的存储大小,可以使用 LENDATALENGTH 函数,如下所示:

SELECT
    val,
    LEN(val) len,
    DATALENGTH(val) data_length
FROM
    dbo.sql_server_nvarchar;

DATETIME2

SQLServer DATETIME2简介

DateTime2是从SQL2008开始支持一个新的日期数据类型。
若要在数据库中同时存储日期和时间,请使用 SQLServer DATETIME2数据类型。

语法如下:

DATETIME2(n)

这个n是秒精度,n的范围是0到7,DATETIME(n)格式是这样的yyyy-MM-dd HH:mm:ss.fffffff,这个n代表的就是f的个数,也就是秒的精度。

下面的语句说明如何创建由 DATETIME2列组成的表:

CREATE TABLE table_name (
    ...
    column_name DATETIME2(3),
    ...
);

DATETIME2有两个组成部分: Date(日期)和Time(时间):

  • 日期的范围从0001年1月01日(0001-01-01)到9999年12月31日(9999-12-31)。
  • 时间的范围从00:00:00到23:59:59.9999999。

DATETIME2(n)值的存储大小取决于秒的精度n的大小,对于小于3的精度,它需要6个字节; 对于介于3和4之间的精度,它需要7个字节; 对于所有其他精度,它需要8个字节。

DATETIME2的格式如下:

YYYY-MM-DD hh:mm:ss[.fff...](f个数为n)

在此格式中:

  • YYYY 是一个四位数字,代表一个年份,例如2018,它的范围从0001到9999。
  • MM 是一个两位数字,表示一年中的一个月,例如12。它的范围从01到12。
  • DD 是两位数字,代表指定月份的某一天,例如23。范围从01到31。
  • hh是代表小时的两位数数字。它的范围从00到23。
  • mm是代表分钟的两位数数字。它的范围从00到59。
  • ss是一个两位数,代表秒。范围从00到59。
  • fff...代表的是秒精度,为0到7位数,范围从0到9999999。具体位数取决于Datetime2(n)中的n

SQL Server DATETIME2示例

以下语句创建了一个数据类型为DateTime2列的新表:

CREATE TABLE dbo.product_colors (
    color_id INT PRIMARY KEY IDENTITY,
    color_name VARCHAR (50) NOT NULL,
    created_at DATETIME2
);

要将当前日期和时间插入create_at 列,可以使用以下带 GETDATE()函数的 INSERT 语句:

INSERT INTO dbo.product_colors (color_name, created_at)
VALUES
    ('Red', GETDATE()); 

GETDATE()函数跟其他数据库系统中的NOW()很想,比如MySQL。

向DATETIME2列中插入字符串格式的日期,请使用以下语句:

INSERT INTO dbo.product_colors (color_name, created_at)
VALUES
    ('Green', '2018-06-23 07:30:20');

如果要将create_at列的默认值设置为当前日期和时间,则使用以下ALTER TABLE语句:

ALTER TABLE dbo.product_colors 
ADD CONSTRAINT df_current_time 
DEFAULT CURRENT_TIMESTAMP FOR created_at;

在此语句中,我们使用 CURRENT_TIMESTAMP 作为 create_at 列的默认值。注意 CURRENT_TIMESTAMP 返回与 GETDATE()函数相同的值。
现在,向表中插入新行而不指定created_at列的值时,SQL Server将使用该列的当前日期和时间值:

INSERT INTO production.product_colors (color_name)
VALUES
    ('Blue');

DATE

SQL Server DATE简介

要存储日期类型,使用DATE类型,语法如下

DATE

不像DATETIME2类型,DATE数据类型只包含日期部分,范围是公元1年1月1日(0001-01-01)到公元9999年12月31日(9999-12-31)。
DATE存储大小固定为3字节,它的格式如下:

YYYY-MM-DD

在此格式中:

  • YYYY 是一个四位数字,代表一个年份,例如2018,它的范围从0001到9999。
  • MM 是一个两位数字,表示一年中的一个月,例如12。它的范围从01到12。
  • DD 是两位数字,代表指定月份的某一天,例如23。范围从01到31,取决于月份。

SQL Server DATE示例

创建如下包含DATE数据类型列order_date的订单表(Order):

CREATE TABLE dbo.orders (
	order_id INT IDENTITY (1, 1) PRIMARY KEY,
	customer_id INT,
	order_status tinyint NOT NULL,
	order_date DATE NOT NULL,
);

以下示例返回订购日期早于2016年1月5日的所有订单:

SELECT    
	order_id, 
	customer_id, 
	order_status, 
	order_date
FROM    
	sales.orders
WHERE order_date < '2016-01-05'
ORDER BY 
	order_date DESC;

输出:

向表中插入数据:

INSERT INTO dbo.orders (
	customer_id, 
	order_status, 
	order_date
)
VALUES
    (
        1001
        2,
        '2019-12-31',
    );

TIME

SQL Server TIME数据类型简介

SQL Server TIME数据类型基于24小时时钟定义一天的时间。时间数据类型的语法如下:

TIME(p)--n是秒精度

TIME(p)类型的格式是hh:mm:ss[.nnnnnnn],其中p代表的是n的个数,也就是秒的精度,p范围是0-7,如果没指定默认是7。

下面的示例说明如何创建具有 TIME 列的表:

CREATE TABLE table_name(
    ...,
    start_at TIME(0),
    ...
);

TIME 值的默认格式为:

hh:mm:ss[.nnnnnnn]

在这个格式中:

  • hh是代表小时的两位数数字。它的范围从00到23。
  • mm是代表分钟的两位数数字。它的范围从00到59。
  • ss是一个两位数,代表秒。范围从00到59。
  • nnnnnnn代表的是秒精度,为0到7位数,范围从0到9999999。具体位数取决于Date(p)中的p。

SQL Server TIME数据类型示例

下面的语句创建了一个名为sales.visits的表,其中包含两个 TIME 列,用于记录客户访问特定商店的时间:

CREATE TABLE sales.visits (
    visit_id INT PRIMARY KEY IDENTITY,
    customer_name VARCHAR (50) NOT NULL,
    phone VARCHAR (25),
    store_id INT NOT NULL,
    visit_on DATE NOT NULL,
    start_at TIME (0) NOT NULL,
    end_at TIME (0) NOT NULL,
    FOREIGN KEY (store_id) REFERENCES sales.stores (store_id)
);

sales.visits表插入一行数据:

INSERT INTO sales.visits (
    customer_name,
    phone,
    store_id,
    visit_on,
    start_at,
    end_at
)
VALUES
    (
        'John Doe',
        '(408)-993-3853',
        1,
        '2018-06-23',
        '09:10:00',
        '09:30:00'
    );

DATETIMEOFFSET

DATETIMEOFFSET数据类型简介

DATETIMEoffSET允许您操作任何单个时间点,这是一个日期时间值,以及一个偏移量,该偏移量指定该日期时间与UTC(世界协调时间)的差异。

DATETIMEOFFSET语法如下:

DATETIMEOFFSET(p)

p代表秒精度(即秒小数点位数),范围时0-7,
若要声明 DATETIMEOffSET 变量,请使用以下语法:

DECLARE @dt DATETIMEOFFSET(7)

若要创建数据类型为 DATETIMEOffSET 的表列:

CREATE TABLE table_name (
    ...,
    column_name DATETIMEOFFSET(7)
    ...
);

DATETIMEOffSET 的范围从公元1年1月1日(0001-01-01)到公元9999年12月31(9999-12-31)日。时间范围从00:00:00到23:59:59.9999999。

DATETIMEOffSET值的格式如下:

YYYY-MM-DDThh:mm:ss[.nnnnnnn][{+|-}hh:mm]

比如:

2020-12-12 11:30:30.12345 

或国际标准化组织格式:

YYYY-MM-DDThh:mm:ss[.nnnnnnn]Z

比如:

2020-12-12 19:30:30.12345Z.

时区偏移

对于日期时间或时间值,时区偏移量指定相对于 UTC 的区偏移量。时区偏移量表示为[+|-] hh:mm.
比如中国本地时(中国标准时间-CST)相对于UTC偏移量就是+8:00,所以中国本地使用的时间就是UTC +8:00时间。

对于语法中的的[+|-] hh:mm:

  • hh是两位数字,范围从00到14,表示时区偏移中的小时数。
  • mm是两个数字,范围从00到59,表示时区偏移中额外的分钟数。
  • +(加)或-(减)指定时区偏移量是从 UTC 时间中加入还是减去,以返回本地时间。

时区偏移量的有效范围为 -14:00至 + 14:00

DATETIMEOFFSET示例

首先,创建一个名为messages的表,该表有一个DATETIMEOFFSET列:

CREATE TABLE messages(
    id         INT PRIMARY KEY IDENTITY, 
    message    VARCHAR(255) NOT NULL, 
    created_at DATETIMEOFFSET NOT NULL
);

然后,在message表中插入一个具有 DATETIMEOffSET 值的当前UTC时间:

INSERT INTO messages(message,created_at)
VALUES('DATETIMEOFFSET demo',
        CAST(getutcdate() AS DATETIMEOFFSET));

最后,从messages表中查询数据,并使用中国标准时间时区(CST)将存储的DATETIMEOFFSET值(UTC)转换为“中国标准时间”时区。

SELECT 
    id, 
    message, 
	created_at 
        AS '世界协调时间'
    created_at AT TIME ZONE 'China Standard Time' 
        AS '中国标准时间',
FROM 
    messages;

通过SQL Server内置的视图sys.time_zone_info,可以查看目标时区的名称:

select * from sys.time_zone_info

输出:

详情参考官网

GUID

SQL Server GUID简介

我们世界上所有的东西都有编号,例如,书有ISBN,汽车有VIN,人有身份证号码。

数字或标识符帮助我们明确地引用事物。例如,我们可以用身份证号511023198423854213来识别他。

全局唯一标识符或 GUID 是这类 ID 号码的一个更广泛的版本。

GUID保证在表、数据库甚至服务器之间是唯一的。

在SQL Server中,GUID是16字节二进制数据类型,使用NEWID()函数生成:

SELECT 
    NEWID() AS GUID;

如果多次执行上述语句,每次都会看到不同的值。以下是其中之一:

GUID
------------------------------------
3297F0F2-35D3-4231-919D-1CFCF4035975

(1 row affected)

在 SQLServer 中,UNIQUEIDENTIFIER 数据类型保存GUID值。
以下语句声明了类型为UNIQUEIDENTIFIER的变量,并为其分配了NEWID()函数生成的GUID值。

DECLARE 
    @id UNIQUEIDENTIFIER;

SET @id = NEWID();

SELECT 
    @id AS GUID;

输出:

GUID
------------------------------------
69AA3BA5-D51E-465E-8447-ECAA1939739A

(1 row affected)

使用SQL Server GUID值作为主键

有时,我更喜欢为表的主键列使用GUID值,而不是使用整数。
使用GUID作为表的主键具有以下优点:

  • GUID值在表,数据库甚至服务器之间是全球唯一的。因此,它允许您轻松合并来自不同服务器的数据。
  • GUID值不暴露信息,因此在URL等公共界面中使用更安全。例如,如果您有URLhttps://www.example.com/customer/100/URL,不难发现将有id为101、102等的客户。但是,使用GUID,这是不可能的:https://www.example.com/customer/F4AB02B7-9D55-483D-9081-CC4E3851E851/

除了这些优点外,将GUID存储在表的主键列中还有以下缺点:

  • GUID值(16字节)比INT(4字节)甚至BIGINT(8字节)占用更多的存储空间。
  • GUID值使调试bug变得复杂,比如id=100与id=F4AB02B7-9D55-483D-9081-CC4E3851E851。

SQL Server GUID示例

创建一个名为customers的新表:

CREATE TABLE dbo.customers(
    customer_id UNIQUEIDENTIFIER DEFAULT NEWID(),
    first_name NVARCHAR(100) NOT NULL,
    last_name NVARCHAR(100) NOT NULL,
    email VARCHAR(200) NOT NULL
);

插入两行数据:

INSERT INTO 
    dbo.customers(first_name, last_name, email)
VALUES
    ('John','Doe','john.doe@example.com'),
    ('Jane','Doe','jane.doe@example.com');

查询数据:

SELECT 
    customer_id, 
    first_name, 
    last_name, 
    email
FROM 
    dbo.customers;

输出:

本文详解了几乎所有的SQL Server数据类型,如果还有问题,欢迎加QQ(2439739932)与我交流.

posted @ 2022-07-29 16:21  平元兄  阅读(1625)  评论(2编辑  收藏  举报