主日期违反日期时间,具有不同的值

时间:2015-09-21 15:34:32

标签: sql-server tsql datetime primary-key

让我们忽略datetime被用作主键的事实。

鉴于以下内容:

DECLARE @table table (test datetime primary key)

INSERT INTO @table
(
    test
)
select
    '2015-09-21 00:00:00.001' -- test - datetime
-- successful insert 

INSERT INTO @table
(
    test
)
select
    '2015-09-21 00:00:00.002' -- test - datetime
-- successful insert

INSERT INTO @table
(
    test
)
select
    '2015-09-21 00:00:00.003' -- test - datetime
-- fails due to primary key violation

select * from @table

SQL Fiddle with only first 2 inserts

SQL Fiddle with all 3 inserts, fails on third insert

这里发生了什么?所有三个“尝试”插入的值都是不同的,但.002.003被视为“相同的值”

4 个答案:

答案 0 :(得分:12)

datetime数据类型没有那么多精度。尝试此查询以查看这些值会发生什么。 datetime数据类型仅精确到.003。 https://msdn.microsoft.com/en-us/library/ms187819.aspx

select CAST('2015-09-21 00:00:00.001' as datetime) union all
select '2015-09-21 00:00:00.002' union all
select '2015-09-21 00:00:00.003'

答案 1 :(得分:6)

  

日期时间值四舍五入为.000,.003或.007的增量   秒,如下表所示。

enter image description here

来源MSDN SQL Server Datetime

因此,您的表值2015-09-21 00:00:00.002四舍五入为2015-09-21 00:00:00.003,在您上次插入时,您会获得主键违规。

日期时间可能是让您使用主键的最差数据类型之一。在表中查找备用列或添加代理列以充当主键列。

答案 2 :(得分:3)

看起来它没有考虑毫秒的不同部分,但如果你使用 angular .module('caseApp', ['ui.router', 'ngResource', "kendo.directives"]) .config( function ($stateProvider, $urlRouterProvider) { $stateProvider .state('edit', { url: '/Edit', templateUrl: '/Clients/ClientEdit' }) 作为数据类型,那么它将成功,因为DATETIME2将产生更好的精度。请尝试以下:

DATETIME2

答案 3 :(得分:2)

那些不是唯一的

精度 舍入为.000,.003或.007秒的增量

也许不使用datetime作为PK

datetime (Transact-SQL)