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日から開始し、しばらくdatetime2してdateその開始日として0001-01-01を使用しています。

私も理解していない何か、ということですdatetimeが表示されますが、リトルエンディアンしばらくするdatetime2と、dateビッグエンディアンです。その場合、どうすれば適切に並べ替えることができますか?

dateタイプによって表される整数の日数を知りたいかどうかを検討してください。あなたはこれを行うことができると思います:

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

しかし、エンディアンのため、1966600日になります!

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か?データ型の内部表現を掘り下げる必要はありません。
Jon Seigel 2013

よると、この、あなたが(「ユーザー定義フォーマットでのUDTの実装」までスクロールダウン)することができますを実装しIComparable、それだけで、クライアント側が使用されています。SQL Serverはそれを無視し、バイトオーダーをオフにします。
Matt Johnson-Pint 2013

ああ。まあそれは迷惑です。
Jon Seigel 2013

@PaulWhite-それは本当に便利です。少なくともそれは私が経験していることの確認です。ありがとう!
Matt Johnson-Pint 2013

@PaulWhite-その記事で彼が触れていない部分は、nullの先頭バイトを削除する方法です。intを5バイトで格納する必要があるのはなぜですか?
Matt Johnson-Pint 2013

回答:


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-similar-mechanism-for-udts


Microsoftは、さまざまなデータ型がどのように格納され、処理されるかについての詳細を公開していません。ただし、Books Onlineは、特定のデータ型について特定のバイナリ形式に依存することはできず、それらが使用する形式はいつでも変更される可能性があることを明確に述べています。したがって、次のSPの後でデータを読み取ることができなくなる可能性があるため、VARBINARYではなく、INTをそのまま格納することをお勧めします。

並べ替えについて:ほとんどのSQL ServerコアはC ++で記述されています。内部的にはiComparableと同様のメソッドが使用されていると想定しています。しかし、繰り返しになりますが、これについて公開されているドキュメントはありません。たとえそうであっても、.NETとC ++には固有の違いがあるため、おそらくそれを利用することはできません。


そこに言及されている他の問題番号も有益でした。しかし、内部型がそれをどのように行うかについて何か詳細がありますか?
Matt Johnson-Pint 2013

@MattJohnson、上記の私の更新を参照してください。私はそれがあなたが探していたものではないことを恐れています...
Sebastian Meine

では、SQL intを私のCLR UDTのバッキングフィールドとして使用することをお勧めしますか?その方法の例はありますか?CREATE TYPEステートメントがかかりますbase_type、または外部アセンブリ-両方ではありません。
Matt Johnson-Pint 2013

いいえ、それは単なる例でした。iComparableインターフェイス(または同様のもの)を実装してSQL Serverで使用する現在の方法がないため、UDTをシリアル化してバイナリソートできるようにする方法を見つける必要があると私は言っています。
Sebastian Meine 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.