如何将SQL中任何格式的varchar转换为datetime

如何将SQL中任何格式的varchar转换为datetime,sql,sql-server,sql-server-2008,datetime,Sql,Sql Server,Sql Server 2008,Datetime,假设我创建了一个表,并按如下所示插入数据 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)),

假设我创建了一个表,并按如下所示插入数据

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
两件事。首先,您需要在转换回datetime时指定样式。第二,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

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

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部分)


“如何解决此问题”-首先不要将日期存储为字符串?记录2和记录3分别以'dd/mm/yy'和'mm/dd/yy'格式存储。假设您在3月4日运行此查询,它们将存储为'04/03/16'和'03/04/16'。计算机无法判断这是3月3日还是4月4日。事实上,人类是不可能知道的。。。!假设您无法控制数据库(否则,不要像Mitch说的那样将日期存储为字符串),则不可能更正这些日期。
03-04-2016
代表什么日期?四月三日还是三月四日?如果您不知道,您将如何告诉sql server对此进行解释?您可以在转换回datetime时使用该样式,例如convert(datetime,yourDateColumn,112),但是如果您有更多具有不同样式的行,您应该使用datetime数据类型来存储日期。文档列出了可能的样式。
SELECT (CASE WHEN ISDATE(datetimeVarchar) = 1 THEN CAST(datetimeVarchar AS DATETIME) 
        ELSE [*Use logic to convert/skip other string values here*] END )
from datetimefromat