Reputation: 3276
I have a table that has a datetime and a time field where the datetime is actually just the date and the time field is the time. I need to combine these 2 fields to create a "created_time" computed field. I'd like to persist this computed field but I keep getting a "non-deterministic" error when I'm trying to combine them. Firstly, I'm not sure I understand why it's non-determinstic, but secondly, is there any fancy way to get around that and accomplish this?
--------------------------------------------------------
date (datetime) | time (varchar)
--------------------------------------------------------
2021-05-05 00:00:00 | 12:00
2021-05-13 00:00:00 | 18:01
I've tried using the following computations and neither work.
ALTER TABLE dbo.table ADD created_time AS ([date] + [time]) PERSISTED
ALTER TABLE dbo.table ADD created_time AS (DATEADD(millisecond, DATEDIFF(millisecond, 0, [time]), [date])) PERSISTED
Upvotes: 3
Views: 808
Reputation: 72194
Firstly, the +
operator is not valid for date
and time
values, strange as it may seem. So you need to use your second version.
Secondly, your time
column is actually varchar
, so the conversion is an implicit non-deterministic conversion.
You can make it deterministic by using CONVERT
with a deterministic style parameter, such as 108 in this case:
ALTER TABLE dbo.[table] ADD created_time AS
(DATEADD(millisecond,
DATEDIFF(millisecond, 0, CONVERT(time, [time], 108)),
[date])) PERSISTED;
This is documented here, some style parameters are not deterministic, because it can depend on culture and century (where year is two-digits).
I strongly suggest you either convert your time
column into the time
data type, or better yet, change it to a combined datetime
column:
ALTER TABLE dbo.[table]
ALTER COLUMN [time] time NOT NULL;
-- or
ALTER TABLE dbo.[table] ADD created_time datetime NULL;
UPDATE dbo.[table]
SET created_time = (DATEADD(millisecond,
DATEDIFF(millisecond, 0, CONVERT(time, [time], 108)),
[date]));
ALTER TABLE dbo.[table]
DROP COLUMN [time]
DROP COLUMN [date];
ALTER TABLE dbo.[table] ALTER created_time datetime NOT NULL;
Upvotes: 2