2010-01-20 5 views
6

Gemäß der Dokumentation können native (binäre) Daten mit BCP importiert oder exportiert werden, das in den nativen SQL Server-Datenformaten formatiert ist. Beispiele hierfür sind SQLFLT8, SQLFLT4, SQLMONEY oder SQLNUMERIC.Was sind die binären Speicherformate für sqflt8, sqlmoney und andere native SQL-Datentypen?

Kennt jemand, was die Datenformate für die verschiedenen Typen sind oder wo Dokumentation, die diese Formate angibt, gefunden werden kann. Zum Beispiel, ist ein SQLFLT8 als IEEE Double Precision Number oder in einem anderen Format gespeichert?

Edit: Aus den Antworten von kevchadders und Andrew hatte ich ein wenig Epiphanie einen wenig googeln für #define und typedef tat, um zu sehen, ob ich C-Header-Dateien mit Definitionen finden kann. Dies kam mit einer Datei odbcdss.h; Die answer Ich habe unten veröffentlicht hat einige Auszüge aus der Datei, die ziemlich vielversprechend aussieht.

+0

+1 gute Frage – kevchadders

Antwort

4

Ich bin mir nicht sicher, ob die Theorie halten wird, aber den internen Speicher der Typen herauszufinden, kann mit ein wenig SQL und etwas herausfinden erreicht werden. Ich habe dies für das neue datetime2/datetimeoffset in meinem Blog getan, um speziell das interne binäre Format zu erhalten, da ich interessiert war, wie sie die zusätzliche Genauigkeit erhalten haben.

Als Beispiel für Geld

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 

Ausgang: 0x000000000001E208

Der 123400 ist, wenn sie als Dezimalzahl in Betracht gezogen, um Geld zu 4 Dezimalstellen gespeichert, so dass 12,3400 als Wert anzeigen würde, Wende- dies in der Theorie ein Wert von nur 1 in hex sollte 0,0001

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

Ausgänge sein 0,0001

Das nächste, was ich dann die negativen Zahlen würde überprüfen, ist

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 

Ausgang: 0xFFFFFFFFFFFE1DF8

, dass so aussieht wie es eine signierte 8-Byte-Zahl ist, da sie die Anzahl weg nur nehmen hat sich von FF ... usw. Ein schneller Check mit -0.0001 gibt alle 0xFFF .... FFF wie erwartet aus und -0.0002 ergibt 0xFF .... FFE wie erwartet.

Ob dies für BCP gilt, bin ich nicht sicher, aber als ein internes Speicherformat würde ich eine vorzeichenbehaftete 8-Byte-Ganzzahl annehmen, die eine angenommene 4 Dezimalstellen hat.

+0

Die Dokumentation für bcp impliziert, dass die 'nativen' Formate mit der nativen Darstellung der Daten in SQL Server übereinstimmen, die Formate jedoch nicht explizit dokumentiert werden. Einige weitere Suchen haben eine C-Header-Datei mit verschiedenen Typdefinitionen ergeben, die den Datentypen entsprechen und ziemlich vernünftig aussehen. +1 für (a) das Umsetzen von Konvertierungen in binäre() Datentypen innerhalb von SQL Server - was mir nicht in den Sinn gekommen ist - und (b) das mühsame Testen der Hypothese. Gute Antwort. – ConcernedOfTunbridgeWells

+0

Die Datetime-Definition in dieser Datei ist korrekt, die niedrigen 4 Bytes sind die vorzeichenlose Anzahl von 300stel Sekunden, ich habe diese auch dekodiert, als ich datetime2 gemacht habe, um den Unterschied zu zeigen. – Andrew

1

Gute Frage.

Scheint nicht viel im Internet darüber, aber ich fand diese Native File Storage Types (Second Tabelle nach unten), die jeden nativen Dateispeichertyp und was es in der entsprechenden Host-Datei Datentyp aufgezeichnet ist.

z.B. float = SQLFLT8
Real = SQLFLT4
Geld = SqlMoney
numerisch = SQLNUMERIC

Entschuldigt, wenn Sie bereits über diese Liste kommen.

+0

Ich habe bereits gesehen, und andere ähnliche Materialien. Obwohl dieses Material manchmal darauf anspielt, kommt es nicht wirklich heraus und gibt an, ob es sich um maschineneigene Formate handelt. Einiges zusätzliches googeln brachte die c-Header-Datei, die ich in die Änderungen eingefügt habe, auf den Kopf, die den Typdefinitionen für die Typen sehr ähnlich sieht. Siehe unten. – ConcernedOfTunbridgeWells

5

Einige weitere googeln für #define und typedef in Verbindung mit den Datentypen drehte diese Header-Datei (odbcss.h) verknüpft here.. Die erste Zeile enthält #Defines für magische Konstanten, die direkt den Namen der SQL-Datentypen entsprechen. Das untere Snippet enthält einige typefs und struct-Definitionen für sinnvoll aussehende Datenformate für die Typen.

Es sieht so aus, als könnten dies die relevanten Formatdefinitionen sein.

Die entsprechenden Schnipsel sind:

// 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 du founs etwas. +1 – kevchadders

Verwandte Themen