我正在尝试将数据库中的时间值更改为语句。例如,早晨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,它会出现此错误。
谢谢,
答案 0 :(得分:1)
我几乎不知道从这个开始......
为什么要在varchar()字段上多次调用DATEPART?这需要首先隐式转换为日期时间类型,这将是昂贵的。将字符串转换为日期时间并从那里开始工作会好得多。
不要在数据库中存储“早晨”等。使用CASE根据日期时间值导出友好值。您可以直接在SELECT中执行此操作,也可以在VIEW中将其抽象出来。
在此字段上调用DATEPART()也意味着您将来肯定会收到错误,因为您在日期/时间字符串的位置设置了像'Morning'这样的字符串。
DATEPART(MINUTE,x)&gt; = 0且DATEPART(SECOND,x)&gt; = 0将始终返回true。没有负面的分钟或秒钟。
同样,11:59:59的最后比较可以简化为DATEPART(HOUR,d)&lt; 12.轰隆隆。无需看几分钟或几秒钟。 (这也处理小数秒,你可能没有以字符串形式处理。
核心问题是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层中完成,您可以访问用户的位置,语言等,而不是深入数据层。
答案 1 :(得分: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'
答案 2 :(得分: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)