【问题标题】:How to convert varchar to datetime for any format in SQL如何将 varchar 转换为 SQL 中任何格式的日期时间
【发布时间】:2016-07-16 15:31:05
【问题描述】:

假设我已经创建了一个表并插入数据如下

create table datetimefromat
(
     SlNo int identity,
     datetimeVarchar varchar(100)
)
go

DECLARE @now datetime

SET @now = GETDATE()

insert into datetimefromat (datetimeVarchar)  
values (convert(nvarchar(MAX), @now, 0)),
       (convert(nvarchar(MAX), @now, 1)),
       (convert(nvarchar(MAX), @now, 3)),
       (convert(nvarchar(MAX), @now, 5)),
       (convert(nvarchar(MAX), @now, 20)),
       (convert(nvarchar(MAX), @now, 13)),
       (convert(nvarchar(MAX), @now, 22)),
       (convert(nvarchar(MAX), @now, 111));
go

select * from datetimefromat
go

+------+--------------------------+
| SlNo |     datetimeVarchar      |
+------+--------------------------+
|    1 | Mar 29 2016 12:46PM      |
|    2 | 03/29/16                 |
|    3 | 29/03/16                 |
|    4 | 29-03-16                 |
|    5 | 2016-03-29 12:46:32      |
|    6 | 29 Mar 2016 12:46:32:087 |
|    7 | 03/29/16 12:46:32 PM     |
|    8 | 2016/03/29               |
+------+--------------------------+

我想把它转换回正常的日期时间

select 
    *,
    CONVERT(datetime, datetimeVarchar) 
from datetimefromat

但这会导致错误

消息 242,第 16 级,状态 3,第 11 行
将 varchar 数据类型转换为 datetime 数据类型导致值超出范围。

我该如何解决这个问题?

因为我要更新现有记录,将varchar列改为datetime

【问题讨论】:

  • “我该如何解决这个问题” - 首先不要将日期存储为字符串?
  • 记录 2 和 3 分别以 'dd/mm/yy' 和 'mm/dd/yy' 格式存储。假设您在 3 月 4 日运行了此查询,它们将存储为“04/03/16”和“03/04/16”。计算机无法确定这是 3 月 3 日还是 4 月 4 日。事实上,人类无法知道它......!
  • 假设您无法控制数据库(否​​则,不要像 Mitch 所说的那样将日期存储为字符串),则无法更正这些日期。 03-04-2016 代表什么日期? 4月3日还是3月4日?如果你说不出来,你将如何告诉 sql-server 来解释这个?
  • 您可以在转换回日期时间时使用该样式,例如 CONVERT(datetime, yourDateColumn, 112) 但如果您有更多不同样式的行,那么您应该使用上面的评论员存储日期的数据类型。

标签: sql sql-server sql-server-2008 datetime


【解决方案1】:

两件事。首先,您需要在转换回日期时间时指定样式。其次,22 不是有效的样式。

此代码有效:

CREATE TABLE datetimeformat
    (SlNo INT IDENTITY,
    datetimeVarchar VARCHAR(100),
    datetimeFormat INT);
GO

DECLARE @now DATETIME = GETDATE();

INSERT INTO
    datetimeformat (datetimeVarchar, datetimeFormat)
VALUES
    (CONVERT(NVARCHAR(MAX), @now, 0), 0),
    (CONVERT(NVARCHAR(MAX), @now, 1), 1),
    (CONVERT(NVARCHAR(MAX), @now, 3), 3),
    (CONVERT(NVARCHAR(MAX), @now, 5), 5),
    (CONVERT(NVARCHAR(MAX), @now, 20), 20),
    (CONVERT(NVARCHAR(MAX), @now, 13), 13),
--  (CONVERT(NVARCHAR(MAX), @now, 22), 22),
    (CONVERT(NVARCHAR(MAX), @now, 111), 111);
GO

SELECT
    *,
    CONVERT(DATETIME, datetimeVarchar, datetimeFormat)
FROM
    datetimeformat;
GO

【讨论】:

  • MSDN 文档列出了可能的样式。
【解决方案2】:

请尝试以下查询,这可能对您有所帮助

select CAST((CASE WHEN isdate(datetimeVarchar) = 1 THEN datetimeVarchar 
    ELSE SUBSTRING(datetimeVarchar,4,3)+LEFT(datetimeVarchar,3)+RIGHT(datetimeVarchar,2)
    END) AS DATETIME)
from datetimefromat

您可以使用函数isdate 来检查给定值是否为有效日期,并根据结果标志您可以构建自己的逻辑(即else部分)。

SELECT (CASE WHEN ISDATE(datetimeVarchar) = 1 THEN CAST(datetimeVarchar AS DATETIME) 
        ELSE [*Use logic to convert/skip other string values here*] END )
from datetimefromat

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 2013-03-02
    • 2023-04-08
    • 1970-01-01
    • 2019-03-13
    相关资源
    最近更新 更多