AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 325365
Accepted
GaTechThomas
GaTechThomas
Asked: 2023-03-30 03:21:10 +0800 CST2023-03-30 03:21:10 +0800 CST 2023-03-30 03:21:10 +0800 CST

将日期时间值填充到 datetime2 列中

  • 772

今天在code review中看到如下语句:

ALTER TABLE dbo.MyTable ADD CreateDate DATETIME2(0) NOT NULL DEFAULT GETUTCDATE()

GETUTCDATE() 函数返回一个datetime,然后将其填充到一个datetime2列中。

这两种类型不同有什么意义吗?使用 SYSUTCDATETIME() 来创建一个datetime2值会更好吗?

sql-server
  • 1 1 个回答
  • 78 Views

1 个回答

  • Voted
  1. Best Answer
    John K. N.
    2023-03-30T16:03:24+08:002023-03-30T16:03:24+08:00

    您的列CreateDate用于DATETIME2(0)日期定义。从表中检索值时,插入SYSUTCDATETIME()or没有区别。GETUTCDATE()

    让我们把你的表定义变成一个例子:

    CREATE TABLE dbo.MyTable 
      (
      ID int IDENTITY (1,1),
      CreateDate DATETIME2(0) NOT NULL DEFAULT GETUTCDATE(),
      CreateDateSYS DATETIME2(0) NOT NULL DEFAULT SYSUTCDATETIME()
      );
    

    然后我们向表中添加一些值:

    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')
      ;
    

    SYSUTCDATETIME()让我们看看和 之间是否有区别GETUTCDATE():

    SELECT * FROM MyTable;
    
    ID 创建日期 创建日期SYS
    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)如果我们创建一个包含 using 列(精度更高)的表并插入不同的值,那么我们会收到以下结果。

    首先我们创建表:

    CREATE TABLE dbo.MyTableFixed 
      (
      ID int IDENTITY (1,1),
      CreateDate DATETIME2(7) NOT NULL DEFAULT GETUTCDATE(),
      CreateDateSYS DATETIME2(7) NOT NULL DEFAULT SYSUTCDATETIME()
      );
    

    然后我们插入一些具有不同精度的日期时间值:

    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')
      ;
    

    然后我们从表中选择值:

    SELECT * FROM MyTableFixed;
    

    返回以下结果:

    ID 创建日期 创建日期SYS
    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()
      
    • 将日期插入DATETIME2(7)定义的列时,您可能会观察到

      CONVERT_IMPLICIT(datetime2(7),[@1],0)              -- actual value 
      CONVERT_IMPLICIT(datetime2(7),getutcdate(),0)      -- getutcdate()
      
    • sysutcdatetime()插入定义的列时,您不会观察到隐式转换DATETIME2(7)。这是因为不必将值从一种日期时间格式转换为另一种格式。SYSUTCDATETIME()将返回一个真正的DATETIME2(7)格式化值。

      Scalar Operator(sysutcdatetime())                  -- sysutcdatetime()
      

    以下是包含转换的执行计划的屏幕截图CONVERT_IMPLICIT:

    包含 CONVERT_IMPLICIT 的执行计划属性的屏幕截图

    可能的解决方案

    如果您要使用存储更高精度值的ALTER列,那么您可以从切换到.DATETIME2(7)DATETIME2SYSUTCDATETIME()

    如果您不需要这么高的精度,请考虑使用较低的值,因为这会在您的表中占用较少的存储空间:

    Storage Size 6 bytes for precision less than 3.
                 7 bytes for precision 3 or 4.
                 All other precision require 8 bytes.2
    

    参考资料

    • GETUTCDATE(事务处理 SQL)(Microsoft Learn)
    • SYSUTCDATETIME (Transact-SQL) (Microsoft Learn)
    • datetime2 (Transact-SQL) (Microsoft Learn)
    • 6

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve