¿Cuáles son los formatos de almacenamiento binarios para sqflt8, SqlMoney y otros tipos de datos SQL nativas?

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

  •  21-09-2019
  •  | 
  •  

Pregunta

De acuerdo con la documentación, los datos (binario) nativa se puede importar o exportar con formato BCP en los formatos de datos de SQL Server nativos. Ejemplos de estos son SQLFLT8, SQLFLT4, SqlMoney o SQLNUMERIC.

¿alguien sabe bien cuáles son los formatos de datos para los distintos tipos son, o donde podrían encontrarse documentación que especifique estos formatos. Por ejemplo, es una SQLFLT8 almacenada como un número de precisión doble IEEE o en algún otro formato?

Editar A partir de las respuestas de los kevchadders y Andrew que tenía un poco de epifanía hizo un poco de google para #define y typedef para ver si podía encontrar C cabecera de los archivos con las definiciones. Esto ocurrió una odbcdss.h archivo; la respuesta he publicado a continuación tiene algunas tomas eliminadas del archivo, que se ve muy prometedor.

¿Fue útil?

Solución

No estoy seguro de si la teoría llevará a cabo, pero encontrar el almacenamiento interno de los tipos que se puede lograr usando alguna de SQL y un poco de averiguar. Hice esto por el nuevo datetime2 / datetimeoffset en mi blog a speifically obtener el formato binario interno como yo estaba interesado en ver cómo consiguieron la precisión adicional.

A modo de ejemplo para el dinero

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 

Salida: 0x000000000001E208

Eso es 123.400 cuando se considera como un número decimal, el dinero se almacena a 4 decimales de manera que indicaría 12,3400 como el valor, invirtiendo este en teoría un valor de sólo 1 en hexadecimal debe ser 0,0001

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

Salidas 0,0001

Lo siguiente que haría a continuación cheque es el números negativos,

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 

Salida: 0xFFFFFFFFFFFE1DF8

Así que parece que es un número de bytes con signo de 8, ya que acaba de tomar el número de distancia de FF ... etc. Una revisión rápida con -0.0001 da toda 0xFFF .... FFF como se esperaba y -0,0002 da 0xFF .... FFE como se esperaba.

Si esto se cumple para el BCP no estoy seguro, pero como un formato de almacenamiento interno que podría tener una pista sobre un número entero con signo de 8 bytes que ha asumido un 4 decimales.

Otros consejos

Algunos googling adicional para #define y typedef en conjunción con los tipos de datos se presentó este archivo de cabecera (odbcss.h) vinculado aquí. . La primera línea tiene #defines para las constantes mágicas que se corresponden directamente con los nombres de los tipos de datos SQL. El fragmento inferior tiene algunas typefs y definiciones struct por mirar sensata formatos de datos para los tipos.

Parece que estos podrían ser las definiciones de formato pertinentes.

Los fragmentos relevantes son:

// 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

Buena pregunta.

No parece mucho en la web acerca de esto, pero he encontrado este nativo Tipos de archivos de almacenamiento (segunda tabla abajo), que muestra cada tipo de almacenamiento de archivos nativo y lo que se registra en el tipo de datos de archivos de host correspondiente.

por ejemplo. flotar = SQLFLT8
reales = SQLFLT4
dinero = SqlMoney
numérico = SQLNUMERIC

Disculpas si ya han llegado a través de esta lista.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top