8

long値を SQL Server テーブルに次のように保存しますvarbinary(max)

var savedValue = BitConverter.GetBytes(longValue);

ここで、T-SQL クエリでその値を操作する必要がありますが、値を取得しようとすると、次のようになります。

select cast(Value as bigint) from dbo.MyValues

異なる数値を返します。たとえば-8588797048854775808、.NET で保存した場合、T-SQL では次のようになります。33802181122903688

何が問題なのか教えてください。その問題に解決策はありますか?

4

1 に答える 1

13

varbinaryから(およびその逆) へのキャストにbigintは、ネットワーク バイト オーダー (ビッグ エンディアン) が使用されます。 BitConverter実行されているマシンのエンディアンを使用します (x86 および x64 のリトルエンディアン)。

Hence BitConverter.GetBytesrun on -8588797048854775808 (0x88CE7696E7167800) is {0x00,0x88,0xE9,0x18,0x69,0x89,0x31,0x77}, and caston {0x00,0x88,0xE9,0x18,0x69,0x89,0x31,0x77} is 0x0088E91869893177 = 38536887891734903 .

やるべきことは明らかで、最初から 64 ビット整数を 64 ビット整数として格納するだけです。

本当にこの変換を行う必要がある場合:

var savedValue = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(longValue))

バイトをスワップしますが、ビッグエンディアン マシンで実行した場合にバイトをスワップしないという点で移植性もあります。

または、何らかの理由で System.Net 名前空間を使用したくない場合、または 3 つのハンドル以外の型に拡張可能にしたい場合は、IPAddress.HostToNetworkOrder次を使用します。

var savedValue = BitConverter.GetBytes(longValue);
if(BitConverter.IsLittleEndian)
  Array.Reverse(savedValue);
于 2011-12-11T20:35:29.270 に答える