了解MS SQL Server日期类型


8

考虑以下:

declare @dt datetime, @dt2 datetime2, @d date
set @dt  = '2013-01-01'
set @dt2 = '2013-01-01'
set @d   = '2013-01-01'

select convert(varbinary, @dt) as dt,
       convert(varbinary, @dt2) as dt2,
       convert(varbinary, @d) as d

输出:

dt                    dt2                     d
------------------    --------------------    --------
0x0000A13900000000    0x07000000000094360B    0x94360B

现在,我已经从理解的文件datetime有一个较小的范围,并开始从1753年1月1日,而datetime2date使用0001-01-01作为他们的开始日期。

我不明白不过,是datetime似乎是小端,而datetime2date是大端。如果是这样,它们怎么能正确分类?

考虑一下我是否想知道一个date类型代表多少整数天。您会认为您可以这样做:

declare @d date
set @d = '0001-01-31'
select cast(convert(varbinary, @d) as int)

但是由于字节顺序,您可以获得1966080天!

要获得30天的正确结果,您必须将其取反:

select cast(convert(varbinary,reverse(convert(varbinary, @d))) as int)

或者,当然您可以执行以下操作:

select datediff(d,'0001-01-01', @d)

但这意味着在内部某个地方无论如何它都会反转字节。

那么为什么他们要改变字节顺序呢?

我只在乎,因为我正在使用SQLCLR中的自定义UDT进行操作,并且字节的二进制顺序在这里似乎很重要,但是这些内置类型似乎更加灵活。SQL Server是否在内部为每种类型提供一些东西来提供自己的排序算法?如果是这样,是否有一种方法可以用于我的自定义UDT?

另请参阅有关 StackOverflow的一个相关(但不同)问题


您是否尝试实施IComparable?您永远不需要深入研究数据类型的内部表示。
乔恩·塞格尔

根据这个(向下滚动到“实现一个用户定义的格式一UDT”),就可以实现IComparable,但它仅使用的客户端。SQL Server会忽略它,并按字节顺序处理。
马特·约翰逊·品脱

哦。嗯,这很烦人。
乔恩·塞格尔

@PaulWhite-确实有用。至少这是对我正在经历的确认。谢谢!
马特·约翰逊·品脱

@PaulWhite-他在该文章中未提及的部分是如何删除null的前导字节。为什么一个int需要以5个字节存储?
马特·约翰逊

Answers:


2

SQL Server的“自有”数据类型不依赖于二进制顺序。对于CLR数据类型,可以使用iComparable接口,但是正如@MattJohnson所述,SQL Server会忽略它:

http://connect.microsoft.com/SQLServer/feedback/details/252230/sqlclr-provide-the-ability-to-use-icomparable-or-a-like-mechanism-for-udts


Microsoft不会发布有关如何存储和使用不同数据类型的详细信息。但是,联机丛书明确指出,特定的数据类型不能依赖特定的二进制格式,并且它们使用的格式可能随时更改。因此,最好仅将INT而不是VARBINARY存储为INT,因为在下一个SP之后您可能无法再读取数据。

至于排序:大多数SQL Server核心是用C ++编写的。我假设在内部使用类似于iComparable的方法。但同样,没有关于此的可公开访问的文档。即使是这样,由于.NET和C ++之间的固有差异,您可能也将无法利用它。


提到的另一个问题编号也提供了信息。但是您是否有关于内部类型的详细信息?
马特·约翰逊·品脱

@MattJohnson,请参阅上面的更新。恐怕这不是您想要的东西
塞巴斯蒂安·梅因

因此,您建议使用SQL int作为CLR UDT的后备字段?你有一个如何做的例子吗?该CREATE TYPE语句将使用base_type或外部程序集-但不能同时使用。
马特·约翰逊·品脱

不,那只是一个例子。我的意思是,您需要找到一种方法来对UDT进行序列化,以便可以对它进行二进制排序,因为目前没有实现iComparable接口(或类似接口)并使SQL Server使用它的方法。
塞巴斯蒂安·梅因
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.