¿Cuáles son los formatos de almacenamiento binarios para sqflt8, SqlMoney y otros tipos de datos SQL nativas?
-
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.
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.