Quali sono i formati di archiviazione binari per sqflt8, SqlMoney e altri tipi di dati SQL nativi?
-
21-09-2019 - |
Domanda
In base alla documentazione, dati nativi (binari) possono essere importati o esportati con bcp formattati nei formati di dati di SQL Server nativi. Esempi di questi sono SQLFLT8, SQLFLT4, SqlMoney o SQLNUMERIC.
Qualcuno sa neanche quali sono i formati di dati per i vari tipi sono, o dove potrebbero essere trovate documentate questi formati. Ad esempio, è uno SQLFLT8 memorizzato come un numero IEEE doppia precisione o in qualche altro formato?
Modifica Dalle risposte di kevchadders e Andrew ho avuto un po 'epifania ha fatto un po' di googling per #define e typedef per vedere se riuscivo a trovare C file di intestazione con le definizioni. Questo è venuto con un file odbcdss.h
; risposta ho postato qui sotto ha alcuni out-take dal file, che sembra molto promettente.
Soluzione
Non sono sicuro se la teoria si terrà, ma scoprire la memoria interna dei tipi può essere ottenuto utilizzando un po 'di SQL e un po' di capire. Ho fatto questo per il nuovo datetime2 / datetimeoffset sul mio blog per ottenere speifically formato binario interno come ero interessato a vedere come hanno ottenuto la precisione aggiuntivo.
Per fare un esempio prezzo
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
Cioè 123400 quando considerato come un numero decimale, denaro viene immagazzinato a 4 decimali modo che indicherebbe 12,3400 come valore, invertire questo in teoria un valore di appena 1 in esadecimale dovrebbe essere 0,0001
declare @test money
declare @binaryValue binary(8)
set @binaryvalue = 0x0000000000000001
set @test = convert(money,@binaryvalue)
select @test
Uscite 0,0001
La prossima cosa che avrei poi controllare sono i numeri negativi,
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
Quindi, che sembra si tratta di un numero di byte con segno 8, dal momento che ha appena prendere il numero da FF ... ecc. Un rapido controllo con -0,0001 dà tutte 0xFFF .... FFF come previsto e -0,0002 dà 0xFF .... FFE come previsto.
Se questo vale per BCP non sono sicuro, ma come un formato di archiviazione interna vorrei prendere una congettura a un segno a 8 byte intero che ha un presunto 4 cifre decimali.
Altri suggerimenti
Qualche ulteriore googling per #define e typedef in combinazione con i tipi di dati alzato questo file di intestazione (odbcss.h
) legato qui. . La prima linea ha #defines per le costanti magiche che corrispondono direttamente ai nomi dei tipi di dati SQL. Il frammento inferiore ha alcuni typefs e definizioni struct per sensibile alla ricerca formati di dati per i tipi.
Sembra che queste potrebbero essere le pertinenti definizioni di formato.
I frammenti rilevanti sono:
// 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
buona domanda.
non sembra molto sul web di questo, ma ho trovato questo Native Tipi di archiviazione di file (seconda tavola verso il basso), che mostra ogni tipo di archiviazione di file nativo e quello che viene registrata nel tipo di dati file host corrispondente.
es.
float = SQLFLT8
vero = SQLFLT4
soldi = SqlMoney
numerico = SQLNUMERIC
Ci scusiamo se avete già incontrato questa lista.