What are the binary storage formats for sqflt8, sqlmoney and other native SQL data types?

Question!

According to the documentation, native (binary) data can be imported or exported with bcp formatted in the native SQL Server data formats. Examples of these are SQLFLT8, SQLFLT4, SQLMONEY or SQLNUMERIC.

Does anyone know either what the data formats for the various types are, or where documentation specifying these formats might be found. For example, is a SQLFLT8 stored as an IEEE double precision number or in some other format?

Edit: From the answers by kevchadders and Andrew I had a little epiphany did a little bit of googling for #define and typedef to see if I could find C header files with definitions. This came up with a file odbcdss.h; the answer I've posted below has some out-takes from the file, which looks quite promising.



Answers

Good Question.

Doesn't seem much on the web about this but i found this Native File Storage Types (Second table down) which shows each native file storage type and what it is recorded in the corresponding host file data type.

e.g. float = SQLFLT8
real = SQLFLT4
money = SQLMONEY
numeric = SQLNUMERIC

Apologies if you have already come across this list.



I'm not sure if the theory will hold, but finding out the internal storage of the types can be achieved using some SQL and a bit of figuring out. I did this for the new datetime2 / datetimeoffset on my blog to speifically get the internal binary format as I was interested to see how they got the additional accuracy.

As an example for Money

declare @test money
set @test = 12.34
select @test -- shows 12.34 as expected

declare @binaryValue binary(8)
set @binaryvalue = convert(binary(8),@test)
select @binaryvalue 

Output : 0x000000000001E208

That is 123400 when considered as a decimal number, money is stored to 4 decimal places so that would indicate 12.3400 as the value, reversing this in theory a value of just 1 in hex should be 0.0001

declare @test money
declare @binaryValue binary(8)
set @binaryvalue = 0x0000000000000001
set @test = convert(money,@binaryvalue)
select @test

Outputs 0.0001

The next thing I would then check is the negative numbers,

declare @test money
set @test = -12.34
select @test -- shows -12.34 as expected

declare @binaryValue binary(8)
set @binaryvalue = convert(binary(8),@test)
select @binaryvalue 

Output : 0xFFFFFFFFFFFE1DF8

So that looks like it is a signed 8 byte number, since it has just take the number away from FF...etc. A quick check with -0.0001 gives out all 0xFFF....FFF as expected and -0.0002 gives 0xFF....FFE as expected.

Whether this holds for BCP I am not sure, but as an internal storage format I would take a guess at a signed 8 byte integer that has an assumed 4 decimal places.

By : Andrew


This video can help you solving your question :)
By: admin