user1613797
user1613797

Reputation: 1267

Cast rowversion to bigint

In my C# program I don't want to work with byte array, therefore I cast rowversion data type to bigint:

SELECT CAST([version] AS BIGINT) FROM [dbo].[mytable]

So I receive a number instead of byte array. Is this conversion always successful and are there any possible problems with it? If so, in which data type should I cast rowversion instead?

Upvotes: 8

Views: 9998

Answers (2)

piers7
piers7

Reputation: 4414

You can convert in C# also, but if you want to compare them you should be aware that rowversion is apparently stored big-endian, so you need to do something like:

byte[] timestampByteArray = ... // from datareader/linq2sql etc...
var timestampInt = BitConverter.ToInt64(timestampByteArray, 0);
timestampInt = IPAddress.NetworkToHostOrder(timestampInt);

It'd probably be more correct to convert it as ToUInt64, but then you'd have to write your own endian conversion as there's no overload on NetworkToHostOrder that takes uint64. Or just borrow one from Jon Skeet (search page for 'endian').

Upvotes: 3

AdamL
AdamL

Reputation: 13161

rowversion and bigint both take 8 bytes so casting seems possible. However, the difference is that bigint is a signed integer, while rowversion is not.

This is a max value of rowversion that will cast properly to max positive bigint number (9223372036854775807):

select cast(0x7FFFFFFFFFFFFFFF as bigint)

But starting from here, you'll be getting negative numbers:

select cast(0x8000000000000000 as bigint)

I didn't check if the latter cast throws an error in C#.

You problably won't reach more than 9223372036854775807 rows in your table, but still it's something you should know about, and I personally wouldn't recommend doing this unless you are certain that this problem will never occur in your solution.

Upvotes: 7

Related Questions