You can't make SQL Server default to truncating, but you can calculate it by subtracting off the unwanted fractional seconds using dateadd and datepart. We'll use nanoseconds mod 1000 to get the fractional seconds to keep for datetime2(6). For example:
declare @t table(x datetime2(7))
insert @t select '2017-03-28 14:00:59.4106489'
select x, truncated = convert(datetime2(6), dateadd(nanosecond, -datepart(nanosecond, x) % 1000, x)) from @t
x |
truncated |
2017-03-28 14:00:59.4106489 |
2017-03-28 14:00:59.410648 |
This method is more efficient than converting the value to text, truncating the text, and then converting the text back to a datetime2.
Here's another related example, this time targeting datetime2(2) to show the difference between a standard convert and this truncating convert for several inputs. Notice that this uses nanoseconds mod 10000000 to get the fractional seconds to keep for datetime2(2).
declare @test table (D7 datetime2(7));
insert into @test values
('2023-04-14 08:38:59.9999999'),
('2023-04-14 08:38:59.999999'),
('2023-04-14 08:38:59.99999'),
('2023-04-14 08:38:59.9999'),
('2023-04-14 08:38:59.999'),
('2023-04-14 08:38:59.99'),
('2023-04-14 08:38:59.9'),
('2023-04-14 08:38:59');
select
D7,
ConvertD2 = convert(datetime2(2), D7),
TruncateD2 = convert(datetime2(2), dateadd(nanosecond, -datepart(nanosecond, D7) % 10000000, D7))
from @test
order by D7 desc
D7 |
ConvertD2 |
TruncateD2 |
2023-04-14 08:38:59.9999999 |
2023-04-14 08:39:00.00 |
2023-04-14 08:38:59.99 |
2023-04-14 08:38:59.9999990 |
2023-04-14 08:39:00.00 |
2023-04-14 08:38:59.99 |
2023-04-14 08:38:59.9999900 |
2023-04-14 08:39:00.00 |
2023-04-14 08:38:59.99 |
2023-04-14 08:38:59.9999000 |
2023-04-14 08:39:00.00 |
2023-04-14 08:38:59.99 |
2023-04-14 08:38:59.9990000 |
2023-04-14 08:39:00.00 |
2023-04-14 08:38:59.99 |
2023-04-14 08:38:59.9900000 |
2023-04-14 08:38:59.99 |
2023-04-14 08:38:59.99 |
2023-04-14 08:38:59.9000000 |
2023-04-14 08:38:59.90 |
2023-04-14 08:38:59.90 |
2023-04-14 08:38:59.0000000 |
2023-04-14 08:38:59.00 |
2023-04-14 08:38:59.00 |
substring('2017-03-28 14:00:59.4106489',1,26)
. Btw, imho both results are wrong, Standard SQL doesn't allow truncating a timestamp, but when you request something like CURRENT_TIMESTAMP(2) it's truncated, not rounded :-)datetime(6)
type or (dateime) methods to truncate the values to microsecond accuracy?