将字符串转换为日期时间问题

时间:2009-09-27 14:49:39

标签: sql sql-server tsql sql-server-2000

使用SQL Server 2000:

SELECT PERSONID, 
       CARDEVENTDATE, 
       INTIME, 
       CASE 
         WHEN OUTTIME = INTIME THEN 
           'No PunchOut' 
         ELSE 
            OUTTIME 
       END AS OUTTIME, 
       CONVERT(char(8), CASE 
                          WHEN DateAdd(Day, - DateDiff(Day, 0, OutTime), OutTime) > '18:00:00' THEN 
                            Cast('18:00:00' AS datetime) 
                          ELSE 
                            DateAdd(Day, - DateDiff(Day, 0, OutTime), OutTime) 
                        END - CASE 
                                WHEN DateAdd(Day, - DateDiff(Day, 0, InTime), InTime) < '09:00:00' THEN 
                                  Cast('09:00:00' AS datetime) 
                                ELSE 
                                  DateAdd(Day, - DateDiff(Day, 0, InTime), InTime) 
                              END, 8) AS WorkTime
  FROM (SELECT T_PERSON.PERSONID,
               T_CARDEVENT.CARDEVENTDATE, 
               MIN(T_CARDEVENT.CARDEVENTTIME) AS INTIME, 
               MAX(T_CARDEVENT.CARDEVENTTIME) AS OUTTIME
          FROM T_PERSON 
    INNER JOIN T_CARDEVENT ON T_PERSON.PERSONID = T_CARDEVENT.PERSONID 
      GROUP BY T_PERSON.PERSONID, T_CARDEVENT.CARDEVENTDATE) DERIVEDTBL

T_cardevent.cardeventtime列数据类型为Varchar。

表中Cardeventtime值为080002,091235 ....所以......,

执行上述查询时,显示Arithmetic Express Overflow错误,将表达式转换为数据类型Datetime。

2 个答案:

答案 0 :(得分:2)

所以这个“080002”代表什么? 8小时0分2秒?

这绝对不是开箱即用的有效DATETIME格式 - 它也不符合任何有效的SQL Server CONVERT styles

因此,您必须自己手动进行一些转换。你有没有机会用这个列将表包装到一个可以处理转换的视图中?

你必须做一些事情:

  CONVERT(DATETIME, SUBSTRING(CardEventTime, 1, 2) + ':' + 
                    SUBSTRING(CardEventTime, 3, 2) + ':' +
                    SUBSTRING(CardEventTime, 5, 2), 8)

这应该将您的“080002”转换为“08:00:02”,然后可以使用样式号将其转换为DATETIME(直到SQL Server 2008没有单独的时间数据类型)。 8(hh:mm:ss)。

马克

答案 1 :(得分:0)

我在这里做了一系列的假设,但没有能够测试它,但这是一个可能的解决方案:

SELECT PERSONID, 
       CARDEVENTDATE, 
       INTIME, 
       CASE 
         WHEN OUTTIME = INTIME THEN 
           'No PunchOut' 
         ELSE 
            OUTTIME 
       END AS OUTTIME, 
    Stuff(Stuff(Right('000000' +
        CONVERT(varchar(5), CASE 
                          WHEN Convert(int,OutTime) > 180000 THEN 
                            180000
                          ELSE 
                            Convert(int,OutTime)
                        END - CASE 
                                WHEN Convert(int,InTime) < 90000 THEN 
                                  90000 
                                ELSE 
                                  Convert(int,InTime) 
                              END), 6),5,0,':'),3,0,':')
        AS WorkTime
  FROM (SELECT T_PERSON.PERSONID,
               T_CARDEVENT.CARDEVENTDATE, 
               MIN(T_CARDEVENT.CARDEVENTTIME) AS INTIME, 
               MAX(T_CARDEVENT.CARDEVENTTIME) AS OUTTIME
          FROM T_PERSON 
    INNER JOIN T_CARDEVENT ON T_PERSON.PERSONID = T_CARDEVENT.PERSONID 
      GROUP BY T_PERSON.PERSONID, T_CARDEVENT.CARDEVENTDATE) DERIVEDTBL

我没有频繁使用Stuff,因此插入点可能已关闭。