1

我正在尝试将数据库中的时间值更改为语句。例如,上午 06:00:00 到 12:00:00 之间的时间间隔,下午 12:00:00 到 17:00:00 之间的时间间隔等等。我正在使用这样的方法:

Update dbo.denouncement_term_day_time

Set time_den = 'Morning'

WHERE (DATEPART(HOUR, time_den) >= 6
  AND DATEPART(MINUTE, time_den) >= 00
  AND DATEPART(SECOND, time_den) >= 00) AND
  (DATEPART(HOUR, time_den) <= 11
  AND DATEPART(MINUTE, time_den) <= 59
  AND DATEPART(SECOND, time_den) <= 59)

但是现在,它不起作用,它给了我错误“从字符串转换日期和/或时间时转换失败。” 即使时间是varchar。正如我所说,如果它适用于前 50-100 行,它适用于相同的数据。但是对于 250,000 raw 它给出了这个错误。

谢谢,

4

3 回答 3

1

我几乎不知道从哪里开始这个...

  1. 为什么您要在 varchar() 字段上多次调用 DATEPART?这需要首先隐式转换为日期时间类型,这将是昂贵的。将字符串转换为日期时间并从那里开始工作会更好。

  2. 不要在您的数据库中存储“Morning”等。使用 CASE 根据日期时间值导出友好值。您可以直接在 SELECT 中执行此操作,或在 VIEW 中将其抽象出来。

  3. 在此字段上调用 ​​DATEPART() 还意味着您一定会在将来遇到错误,因为您正在设置像 'Morning' 这样的字符串来代替日期/时间字符串。

  4. DATEPART(MINUTE, x) >= 0 和 DATEPART(SECOND, x) >=0 将始终返回 true。没有负分或秒之类的东西。

  5. 同样,最后一次比较 11:59:59 可以简化为 DATEPART(HOUR, d) < 12。Boom。无需查看分钟或秒。(这也处理小数秒,您可能没有以字符串形式处理。

核心问题是 varchar() 字段中的某些内容不是可以隐式转换回来的日期/时间。

我的解决方案,使用计算列:

  -- Add a new column for the proper datetime values.
  ALTER TABLE denouncement_term_day_time ADD datetime_den datetime;
  -- Clean your data before running the next line.
  UPDATE denouncement_term_day_time SET datetime_den = CAST(time_den AS datetime);
  -- Once converted, don't store the string dates anymore, it's wasteful
  ALTER TABLE denouncement_term_day_time DROP COLUMN time_den;
  -- Add a computed column to return the friendly time.
  ALTER TABLE denouncement_term_day_time ADD friendly_time AS
        CASE
          WHEN DATEPART(HOUR, datetime_den) > 16 THEN 'Evening'
          WHEN DATEPART(HOUR, datetime_den) > 11 THEN 'Afternoon'
          ELSE 'Morning'
        END

然而,即使这样也有问题,因为它假设用户与数据处于同一时区。理想情况下,这类事情应该在 UI 层中完成,在那里您可以访问用户的位置、语言等,而不是深入数据层。

于 2013-08-30T06:59:00.860 回答
0

试试这个

Update dbo.denouncement_term_day_time
   Set time_den = 'Morning'
WHERE (DATEPART(HOUR,  Convert(DATETIME, [time_den]), 8)) >= 6
AND DATEPART(MINUTE,  Convert(DATETIME, [time_den]), 8)) >= 00
AND DATEPART(SECOND,  Convert(DATETIME, [time_den]), 8)) >= 00) 
AND ( DATEPART(HOUR,  Convert(DATETIME, [time_den]), 8)) <= 11
AND DATEPART(MINUTE,  Convert(DATETIME, [time_den]), 8)) <= 59
AND DATEPART(SECOND,  Convert(DATETIME, [time_den]), 8)) <= 59)
于 2013-08-30T07:13:52.340 回答
0

试试这个——

ALTER TABLE dbo.denouncement_term_day_time
    ADD time_den_new VARCHAR(20) NULL
GO

UPDATE dbo.denouncement_term_day_time
SET time_den_new = 
        CASE WHEN time_den BETWEEN '6:00:00' AND '11:59:59' THEN 'Morning'
             WHEN time_den BETWEEN '12:00:00' AND '16:59:59' THEN 'Afternoon'
        END
WHERE time_den BETWEEN '6:00:00' AND '16:59:59'
GO

ALTER TABLE dbo.denouncement_term_day_time DROP COLUMN time_den
GO

EXEC sp_rename 'dbo.denouncement_term_day_time.time_den_new', 'time_den', 'COLUMN'
于 2013-08-30T06:55:58.050 回答