GaT*_*mas 6 sql-server datetime
今天在代码审查中看到这样的说法:
ALTER TABLE dbo.MyTable ADD CreateDate DATETIME2(0) NOT NULL DEFAULT GETUTCDATE()
Run Code Online (Sandbox Code Playgroud)
GETUTCDATE() 函数返回 a datetime,然后将其填充到datetime2列中。
这两种类型的不同有什么意义吗?使用 SYSUTCDATETIME() 创建datetime2值会更好吗?
您的列CreateDate用于DATETIME2(0)日期定义。从表中检索值时,插入SYSUTCDATETIME()或没有区别。GETUTCDATE()
让我们以您的表定义为例:
CREATE TABLE dbo.MyTable
(
ID int IDENTITY (1,1),
CreateDate DATETIME2(0) NOT NULL DEFAULT GETUTCDATE(),
CreateDateSYS DATETIME2(0) NOT NULL DEFAULT SYSUTCDATETIME()
);
Run Code Online (Sandbox Code Playgroud)
然后我们向表中添加一些值:
INSERT INTO MyTable (CreateDate, CreateDateSYS)
VALUES
(GETUTCDATE(),GETUTCDATE()),
(SYSUTCDATETIME(), SYSUTCDATETIME()),
('2023-03-30 07:16:45.1','2023-03-30 07:16:45.1'),
('2023-03-30 07:16:45.12','2023-03-30 07:16:45.12'),
('2023-03-30 07:16:45.123','2023-03-30 07:16:45.123'),
('2023-03-30 07:16:45.1234','2023-03-30 07:16:45.1234'),
('2023-03-30 07:16:45.12345','2023-03-30 07:16:45.12345')
;
Run Code Online (Sandbox Code Playgroud)
SYSUTCDATETIME()让我们看看和 之间是否有区别GETUTCDATE():
SELECT * FROM MyTable;
Run Code Online (Sandbox Code Playgroud)
| ID | 创建日期 | 创建日期系统 |
|---|---|---|
| 1 | 2023-03-30 07:21:12 | 2023-03-30 07:21:12 |
| 2 | 2023-03-30 07:21:12 | 2023-03-30 07:21:12 |
| 3 | 2023-03-30 07:16:45 | 2023-03-30 07:16:45 |
| 4 | 2023-03-30 07:16:45 | 2023-03-30 07:16:45 |
| 5 | 2023-03-30 07:16:45 | 2023-03-30 07:16:45 |
| 6 | 2023-03-30 07:16:45 | 2023-03-30 07:16:45 |
| 7 | 2023-03-30 07:16:45 | 2023-03-30 07:16:45 |
正如您所看到的,插入GETUTCDATE()或SYSUTCDATETIME()对存储的内容没有影响。这是因为列(如您的示例中)是使用DATETIME2(0)默认精度定义的。
DATETIME2(7)如果我们创建一个包含使用(精度更高)的列并插入不同值的表,那么我们会收到以下结果。
首先我们创建表:
CREATE TABLE dbo.MyTableFixed
(
ID int IDENTITY (1,1),
CreateDate DATETIME2(7) NOT NULL DEFAULT GETUTCDATE(),
CreateDateSYS DATETIME2(7) NOT NULL DEFAULT SYSUTCDATETIME()
);
Run Code Online (Sandbox Code Playgroud)
然后我们插入一些具有不同精度的日期时间值:
INSERT INTO MyTableFixed (CreateDate, CreateDateSYS)
VALUES
(GETUTCDATE(),GETUTCDATE()),
(SYSUTCDATETIME(), SYSUTCDATETIME()),
('2023-03-30 07:16:45.1','2023-03-30 07:16:45.1'),
('2023-03-30 07:16:45.12','2023-03-30 07:16:45.12'),
('2023-03-30 07:16:45.123','2023-03-30 07:16:45.123'),
('2023-03-30 07:16:45.1234','2023-03-30 07:16:45.1234'),
('2023-03-30 07:16:45.12345','2023-03-30 07:16:45.12345')
;
Run Code Online (Sandbox Code Playgroud)
然后我们从表中选择值:
SELECT * FROM MyTableFixed;
Run Code Online (Sandbox Code Playgroud)
返回以下结果:
| ID | 创建日期 | 创建日期系统 |
|---|---|---|
| 1 | 2023-03-30 07:21:11.5500000 | 2023-03-30 07:21:11.5500000 |
| 2 | 2023-03-30 07:21:11.5508485 | 2023-03-30 07:21:11.5508485 |
| 3 | 2023-03-30 07:16:45.1000000 | 2023-03-30 07:16:45.1000000 |
| 4 | 2023-03-30 07:16:45.1200000 | 2023-03-30 07:16:45.1200000 |
| 5 | 2023-03-30 07:16:45.1230000 | 2023-03-30 07:16:45.1230000 |
| 6 | 2023-03-30 07:16:45.1234000 | 2023-03-30 07:16:45.1234000 |
| 7 | 2023-03-30 07:16:45.1234500 | 2023-03-30 07:16:45.1234500 |
注意:此答案中使用的示例可以在db<>fiddle
上运行和测试
这两种类型的不同有什么意义吗?
CreateDate在您的情况下不是,因为您使用低精度类型定义了列DATETIME2(0)。
SYSUTCDATETIME()用来创造价值会更好吗datetime2?
在您的情况下不是,因为即使您将创建一个DATETIME2高精度的值,您也会将其存储在DATETIME2(0)精度较低的列中。
如果您的问题涉及插入数据时可能对性能产生的影响...
...那么当某些值传递到列时,可能会产生轻微的开销。这是由于发生了隐式转换。这可以从执行计划中获得。
将日期插入到DATETIME2(0)定义的列中时,您可能会观察到
CONVERT_IMPLICIT(datetime2(0),[@1],0) -- actual value
CONVERT_IMPLICIT(datetime2(0),getutcdate(),0) -- getutcdate()
CONVERT_IMPLICIT(datetime2(0),sysutcdatetime(),0) -- sysutcdatetime()
Run Code Online (Sandbox Code Playgroud)
将日期插入到DATETIME2(7)定义的列中时,您可能会观察到
CONVERT_IMPLICIT(datetime2(7),[@1],0) -- actual value
CONVERT_IMPLICIT(datetime2(7),getutcdate(),0) -- getutcdate()
Run Code Online (Sandbox Code Playgroud)
sysutcdatetime()插入到定义的列时,您不会观察到隐式转换DATETIME2(7)。这是因为不必将值从一种日期时间格式转换为另一种日期时间格式。SYSUTCDATETIME()将返回一个真正的DATETIME2(7)格式化值。
Scalar Operator(sysutcdatetime()) -- sysutcdatetime()
Run Code Online (Sandbox Code Playgroud)
以下是包含转换的执行计划的屏幕截图CONVERT_IMPLICIT:
如果您要使用存储更高精度值的ALTER列,那么您可以从切换到.DATETIME2(7)DATETIME2SYSUTCDATETIME()
如果您不需要这么高的精度,请考虑使用较低的值,因为这将占用表中更少的存储空间:
Run Code Online (Sandbox Code Playgroud)Storage Size 6 bytes for precision less than 3. 7 bytes for precision 3 or 4. All other precision require 8 bytes.2