Каковы двоичные форматы хранения для sqflt8, sqlmoney и других типов данных SQL?

StackOverflow https://stackoverflow.com/questions/2099919

  •  21-09-2019
  •  | 
  •  

Вопрос

Согласно документации, собственные (двоичные) данные можно импортировать или экспортировать с помощью bcp, отформатированного в собственных форматах данных SQL Server.Примерами являются SQLFLT8, SQLFLT4, SQLMONEY или SQLNUMERIC.

Кто-нибудь знает, каковы форматы данных для различных типов или где можно найти документацию, определяющую эти форматы.Например, SQLFLT8 хранится как число двойной точности IEEE или в каком-то другом формате?

Редактировать: Из ответов автора Кевчаддеры и Андрей У меня было небольшое прозрение: я немного погуглил #define и typedef, чтобы посмотреть, смогу ли я найти заголовочные файлы C с определениями.Вот появился файл odbcdss.h;тот отвечать Ниже я разместил некоторые выдержки из файла, которые выглядят весьма многообещающе.

Это было полезно?

Решение

Я не уверен, что теория верна, но выяснить внутреннее хранилище типов можно, используя немного SQL и немного разобравшись.Я сделал это для нового datetime2/datetimeoffset в своем блоге, чтобы специально получить внутренний двоичный формат, поскольку мне было интересно посмотреть, как они получили дополнительную точность.

В качестве примера для денег

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 

Выход :0x000000000001E208

Это 123400, если рассматривать его как десятичное число, деньги хранятся с точностью до 4 знаков после запятой, так что в качестве значения будет указано 12,3400, теоретически значение всего 1 в шестнадцатеричном формате должно быть 0,0001.

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

Выходы 0,0001

Следующее, что я хотел бы проверить, это отрицательные числа,

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 

Выход :0xFFFFFFFFFFFE1DF8

Похоже, это 8-байтовое число со знаком, поскольку оно только что забрало число из FF... и т. д.Быстрая проверка с -0,0001 выдает все 0xFFF....FFF, как и ожидалось, а -0,0002 дает 0xFF....FFE, как и ожидалось.

Я не уверен, справедливо ли это для BCP, но в качестве внутреннего формата хранения я бы предположил 8-байтовое целое число со знаком, которое имеет предполагаемые 4 десятичных знака.

Другие советы

Дальнейший поиск в Google #define и typedef в сочетании с типами данных выявил этот заголовочный файл (odbcss.h) связан здесь..В первой строке есть #Defines для магических констант, которые напрямую соответствуют именам типов данных SQL.В нижнем фрагменте есть некоторые определения типов и структур для разумного формата данных для типов.

Похоже, это могут быть соответствующие определения формата.

Соответствующие фрагменты:

// SQL Server Data Type Tokens. Returned by SQLColAttributes/SQL_CA_SS_COLUMN_SSTYPE.
#define SQLTEXT             0x23
#define SQLVARBINARY        0x25
#define SQLINTN             0x26
#define SQLVARCHAR          0x27
#define SQLBINARY           0x2d
#define SQLIMAGE            0x22
#define SQLCHARACTER        0x2f
#define SQLINT1             0x30
#define SQLBIT              0x32
#define SQLINT2             0x34
#define SQLINT4             0x38
#define SQLMONEY            0x3c
#define SQLDATETIME         0x3d
#define SQLFLT8             0x3e
#define SQLFLTN             0x6d
#define SQLMONEYN           0x6e
#define SQLDATETIMN         0x6f
#define SQLFLT4             0x3b
#define SQLMONEY4           0x7a
#define SQLDATETIM4         0x3a
#define SQLDECIMAL          0x37
#define SQLDECIMALN         0x6a
#define SQLNUMERIC          0x3f
#define SQLNUMERICN         0x6c

[ . . . ]

typedef char            DBCHAR;
typedef unsigned char   DBBINARY;
typedef unsigned char   DBTINYINT;
typedef short           DBSMALLINT;
typedef unsigned short  DBUSMALLINT;
typedef long            DBINT;
typedef double          DBFLT8;
typedef unsigned char   DBBIT;
typedef unsigned char   DBBOOL;
typedef float           DBFLT4;

typedef DBFLT4 DBREAL;
typedef UINT   DBUBOOL;

typedef struct dbvarychar
{
    DBSMALLINT  len;
    DBCHAR      str[DBMAXCHAR];
} DBVARYCHAR;

typedef struct dbvarybin
{
    DBSMALLINT  len;
    BYTE        array[DBMAXCHAR];
} DBVARYBIN;

typedef struct dbmoney
{               // Internal representation of MONEY data type
    LONG  mnyhigh;      // Money value *10,000 (High 32 bits/signed)
    ULONG mnylow;       // Money value *10,000 (Low 32 bits/unsigned)
} DBMONEY;

typedef struct dbdatetime
{               // Internal representation of DATETIME data type
    LONG  dtdays;       // No of days since Jan-1-1900 (maybe negative)
    ULONG dttime;       // No. of 300 hundredths of a second since midnight
} DBDATETIME;

typedef struct dbdatetime4
{           // Internal representation of SMALLDATETIME data type
    USHORT numdays;     // No of days since Jan-1-1900
    USHORT nummins;     // No. of minutes since midnight
} DBDATETIM4;

typedef LONG DBMONEY4;  // Internal representation of SMALLMONEY data type
                        // Money value *10,000

#define DBNUM_PREC_TYPE BYTE
#define DBNUM_SCALE_TYPE BYTE
#define DBNUM_VAL_TYPE BYTE
typedef const LPBYTE    LPCBYTE;
typedef DBINT *         LPDBINT;

#if (ODBCVER < 0x0300)
#define MAXNUMERICLEN 16

typedef struct dbnumeric
{                 // Internal representation of NUMERIC data type
    DBNUM_PREC_TYPE   precision; // Precision
    DBNUM_SCALE_TYPE  scale;     // Scale
    BYTE     sign;           // Sign (1 if positive, 0 if negative)
    DBNUM_VAL_TYPE    val[MAXNUMERICLEN];   // Value
} DBNUMERIC;
typedef DBNUMERIC DBDECIMAL;// Internal representation of DECIMAL data type
#else   //  Use ODBC 3.0 definitions since same as DBLib
#define MAXNUMERICLEN SQL_MAX_NUMERIC_LEN
typedef SQL_NUMERIC_STRUCT DBNUMERIC;
typedef SQL_NUMERIC_STRUCT DBDECIMAL;
#endif

#endif //   MAXNUMERICLEN

Хороший вопрос.

Кажется, в Интернете об этом не так много, но я нашел это Собственные типы хранилищ файлов (Вторая таблица вниз), в которой показан каждый собственный тип хранилища файлов и то, что он записан в соответствующем типе данных хост-файла.

напримерс плавающей запятой = SQLFLT8
реальный = SQLFLT4
деньги = SQLMONEY
числовой = SQLNUMERIC

Приносим извинения, если вы уже сталкивались с этим списком.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top