2010-01-20 7 views
6

In base alla documentazione, i dati nativi (binari) possono essere importati o esportati con bcp formattato nei formati di dati nativi di SQL Server. Esempi di questi sono SQLFLT8, SQLFLT4, SQLMONEY o SQLNUMERIC.Quali sono i formati di archiviazione binaria per sqflt8, sqlmoney e altri tipi di dati SQL nativi?

Qualcuno sa o quali sono i formati dei dati per i vari tipi o dove è possibile trovare la documentazione che specifica questi formati. Ad esempio, SQLFLT8 è memorizzato come un numero di precisione doppia IEEE o in qualche altro formato?

modifica: Dalle risposte da kevchadders e Andrew Ho avuto un po 'epifania ha fatto un pò di googling per #define e typedef per vedere se riuscivo a trovare i file di intestazione C con le definizioni. Questo è venuto con un file odbcdss.h; il answer che ho postato di seguito ha alcuni out-take dal file, che sembra abbastanza promettente.

+0

+1 buona domanda – kevchadders

risposta

4

Non sono sicuro che la teoria verrà mantenuta, ma è possibile trovare la memoria interna dei tipi utilizzando un po 'di SQL e un po' di comprensione. Ho fatto questo per il nuovo datetime2/datetimeoffset sul mio blog per ottenere in modo specifico il formato binario interno perché ero interessato a vedere come ottenevano l'accuratezza aggiuntiva.

Come 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 

uscita: 0x000000000001E208

Cioè 123400 quando considerato come un numero decimale, denaro viene memorizzato a 4 decimali modo che indicherebbe 12,3400 come valore, invertendo 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 

uscita: 0xFFFFFFFFFFFE1DF8

Così che sembra si tratta di un numero di byte con segno 8, dal momento che ha appena prendere il numero di distanza dal FF ... ecc. Un rapido controllo con -0.0001 fornisce tutto 0xFFF .... FFF come previsto e -0.0002 dà 0xFF .... FFE come previsto.

Se questo vale per BCP, non sono sicuro, ma come formato di archiviazione interno vorrei fare una supposizione a un intero con 8 byte con segno che ha assunto 4 cifre decimali.

+0

La documentazione per bcp implica che i formati "nativi" sono gli stessi della rappresentazione nativa dei dati in SQL Server, ma non documenta esplicitamente i formati. Alcune ulteriori ricerche hanno generato un file di intestazione C con varie definizioni di tipi che corrispondono ai tipi di dati e sembrano abbastanza sensibili. +1 per (a) pensare di eseguire le conversioni a tipi di dati binary() all'interno di SQL Server - cosa che non mi è venuta in mente - e (b) affrontare il problema di testare l'ipotesi. Buona risposta. – ConcernedOfTunbridgeWells

+0

La definizione Datetime in quel file è corretta, i 4 byte bassi sono il numero senza segno di 300ths di secondo, l'ho decodificato anche quando ho fatto datetime2 per mostrare la differenza. – Andrew

1

Buona domanda.

Non sembra molto presente sul Web ma ho trovato questo Native File Storage Types (Seconda tabella in basso) che mostra ciascun tipo di archiviazione di file nativo e ciò che è registrato nel corrispondente tipo di dati del file host.

ad es. float = SQLFLT8
reale = SQLFLT4
soldi = SqlMoney
numerica = SQLNUMERIC

Ci scusiamo se avete già incontrato questa lista.

+0

Ho già visto questo e altro materiale simile. Sebbene a volte questo materiale vi alluda, in realtà non emerge e indica se si tratta di formati nativi della macchina. Alcuni googling aggiuntivi hanno mostrato il file di intestazione c che ho inserito nelle modifiche, che ha l'aspetto di definizioni di tipo per i tipi. Vedi sotto. – ConcernedOfTunbridgeWells

5

Altri googling per #define e typedef in combinazione con i tipi di dati hanno generato questo file di intestazione (odbcss.h) collegato here.. La prima riga contiene #Defines per le costanti magiche che corrispondono direttamente ai nomi dei tipi di dati SQL. Lo snippet inferiore presenta alcune definizioni di typefs e struct per formati di dati dall'aspetto sensibile per i tipi.

Sembra che queste potrebbero essere le definizioni di formato rilevanti.

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 
+0

Gkad tu mandi qualcosa. +1 – kevchadders

Problemi correlati