Tsql 将DATETIME列与CHAR字段组合以创建DATETIME2列

Tsql 将DATETIME列与CHAR字段组合以创建DATETIME2列,tsql,datetime,sql-server-2016,Tsql,Datetime,Sql Server 2016,我正在尝试从供应商的数据库导入数据,并为我们的数据库将两列合并为一列。它们有两列,分别是CITATION\u DATE和CITATION\u TIME,前者是char(8)数据类型 我想将这两列合并为一列issueDate,属于datetime2(7)数据类型 我尝试使用Aaron找到的逻辑,但没有成功地执行查询。我的怀疑是我需要更多的字符在引文时间中形成一个有效的时间戳,但我不确定 是否有一种方法可以将这两个字段合并成一个列-遵循datetime2格式 我试图清除空字符串或非数字字符等错误值

我正在尝试从供应商的数据库导入数据,并为我们的数据库将两列合并为一列。它们有两列,分别是
CITATION\u DATE
CITATION\u TIME
,前者是
char(8)
数据类型

我想将这两列合并为一列
issueDate
,属于
datetime2(7)
数据类型

我尝试使用Aaron找到的逻辑,但没有成功地执行查询。我的怀疑是我需要更多的字符在
引文时间
中形成一个有效的时间戳,但我不确定

是否有一种方法可以将这两个字段合并成一个列-遵循
datetime2
格式

我试图清除空字符串或非数字字符等错误值:

;WITH issueDate AS
( 
    SELECT 
        TRY_CAST(vt.CITATION_DATE AS DATE) AS CITATION_DATE ,
        CASE WHEN RTRIM ( LTRIM ( vt.CITATION_TIME )) = '' THEN '0000'
             WHEN RTRIM ( LTRIM ( vt.CITATION_TIME )) = '000' THEN '0000'
             WHEN TRY_CAST(vt.CITATION_TIME AS INT) IS NULL THEN '0000'
             ELSE vt.CITATION_TIME
        END AS CITATION_TIME
    FROM   
        Oklahoma_PVD_WildlifeLaw.dbo.VIOLATOR_TICKETS AS vt
    --ORDER BY CITATION_TIME;
)
SELECT 
    CONVERT(DATETIME, CONVERT(CHAR(8), id.CITATION_DATE, 112) + ' ' + 
       CONVERT(CHAR(8), id.CITATION_TIME, 108))
FROM   
    issueDate AS id;
但我得到了以下错误:

将varchar数据类型转换为datetime数据类型导致值超出范围

看起来我的时间部分没有足够的字符,因为这返回了
DATETIME
格式的值,但我以这种方式丢失了所有的小时和分钟:

;WITH issueDate AS 
(
    SELECT 
        TRY_CAST(vt.CITATION_DATE AS DATE) AS CITATION_DATE,
        CASE 
           WHEN RTRIM(LTRIM(vt.CITATION_TIME)) = '' THEN '00:00:00.0000000'
           WHEN RTRIM(LTRIM(vt.CITATION_TIME)) = '000' THEN '00:00:00.0000000'
           WHEN TRY_CAST(vt.CITATION_TIME AS INT) IS NULL THEN '00:00:00.0000000'
           --ELSE vt.CITATION_TIME
        END AS CITATION_TIME
    FROM   
        Oklahoma_PVD_WildlifeLaw.dbo.VIOLATOR_TICKETS AS vt
    --ORDER BY CITATION_TIME;
)
SELECT 
    CONVERT(DATETIME, CONVERT(CHAR(8), id.CITATION_DATE, 112) + ' ' +
        CONVERT(CHAR(8), id.CITATION_TIME, 108)) AS [DateTime]
FROM   
    issueDate AS id
WHERE
    CONVERT(DATETIME, CONVERT(CHAR(8), id.CITATION_DATE, 112) + ' ' +
        CONVERT(CHAR(8), id.CITATION_TIME, 108)) IS NOT NULL;

您是否尝试从时间部分计算分钟数并使用将其添加到日期

此代码假定所有日期都有零时间部分(午夜),引用时间都是数字。上面的代码试图通过强制转换datetime to date(去掉时间部分)并使用try_强制转换来处理非数字时间来处理这些问题。如果需要,可以使用相同的代码:

select DATEADD(minute, t.IntTime % 100 + 60 * (t.IntTime / 100), cast(CITATION_DATE as date))
FROM   Oklahoma_PVD_WildlifeLaw.dbo.VIOLATOR_TICKETS AS vt
cross apply (select isnull(try_cast(CITATION_TIME as int), 0) as IntTime ) t
如果数据中存在无效的“时间”,则必须决定如何处理它们。尝试通过搜索值来查找这些记录,其中最后2位大于等于60,例如:

select * from Oklahoma_PVD_WildlifeLaw.dbo.VIOLATOR_TICKETS
where try_cast(right(CITATION_TIME, 2) as int) >= 60
   or (len(CITATION_TIME) = 4 and try_cast(left(CITATION_TIME, 2) as int) >= 24)       
   or len(CITATION_TIME) > 4

有几个问题。1830年的
引证时间
代表的是
06:30:00 PM
,还是以分钟或秒为单位?另外,
引用时间的
MIN
MAX
值是多少?这是一个好问题-我假设这是军事时间,但我看到的最大值是9799-因此需要客户提出更多问题。数据清理冒险。让我们知道你发现了什么!最大值
9799
让我想知道它是否可能是一天的定点小数:
0.9799天=84663秒
。谢谢-引用列中有无效时间-我看到许多值的前两位大于24。
select * from Oklahoma_PVD_WildlifeLaw.dbo.VIOLATOR_TICKETS
where try_cast(right(CITATION_TIME, 2) as int) >= 60
   or (len(CITATION_TIME) = 4 and try_cast(left(CITATION_TIME, 2) as int) >= 24)       
   or len(CITATION_TIME) > 4