Was sind die Binärspeicherformate für SQFLT8, SQLMoney und andere native SQL -Datentypen?
-
21-09-2019 - |
Frage
Gemäß der Dokumentation können native (binäre) Daten mit BCP -Formaten importiert oder exportiert werden. Beispiele hierfür sind SQLFLT8, SQLFLT4, SQLMONEY oder SQLNUMERIC.
Weiß jemand entweder, was die Datenformate für die verschiedenen Typen sind oder wo Dokumentation, die diese Formate angeben, gefunden werden? Wird beispielsweise ein SQLFLT8 als IEEE -Doppelpräzisionsnummer oder in einem anderen Format gespeichert?
Bearbeiten: Von den Antworten von Kevchadders und Andrew Ich hatte eine kleine Offenbarung, die ein bisschen googelte, um #Define und TypedeFef zu suchen, um zu sehen, ob ich C -Header -Dateien mit Definitionen finden kann. Dies kam mit einer Datei odbcdss.h
; das Antworten Ich habe unten einige Ausfälle aus der Datei gepostet, die ziemlich vielversprechend aussieht.
Lösung
Ich bin mir nicht sicher, ob die Theorie gelten wird, aber die interne Speicherung der Typen zu finden, kann mithilfe einiger SQL und ein wenig herausgefunden werden. Ich habe dies für das neue DateTime2 / DateTimeOffset in meinem Blog getan, um das interne binäre Format speisen 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
Ausgabe: 0x0000000001e208
Das ist 123400, wenn es als Dezimalzahl betrachtet wird, wird Geld auf 4 Dezimalstellen gespeichert, sodass 12.3400 als Wert angezeigt werden, wobei dies theoretisch ein Wert von nur 1 in Hex umgekehrt wird.
declare @test money
declare @binaryValue binary(8)
set @binaryvalue = 0x0000000000000001
set @test = convert(money,@binaryvalue)
select @test
Ausgänge 0,0001
Das nächste, was ich dann überprüfen würde, sind die negativen Zahlen.
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
Ausgabe: 0xfffffffffffffffe1df8
Das sieht also so aus, als wäre es eine signierte 8 -Byte -Nummer, da es gerade die Nummer von FF weggenommen hat ... usw. Ein kurzer Blick mit -0.0001 gibt alle 0xfff .... fff wie erwartet und -0.0002 wie erwartet 0xff ... FFE.
Ob dies für BCP gilt, bin ich mir nicht sicher, aber als internes Speicherformat würde ich an einer signierten 8 -Byte -Ganzzahl erraten, die angenommen hat, dass 4 Dezimalstellen angenommen werden.
Andere Tipps
Einige weitere Googeln für #Define und Typedef in Verbindung mit den Datentypen haben diese Header -Datei (odbcss.h
) verknüpft hier.. Die erste Zeile enthält #defines für magische Konstanten, die direkt den Namen der SQL -Datentypen entsprechen. Das untere Snippet verfügt über einige Signifikationen und Strukturdefinitionen für vernünftig aussehende Datenformate für die Typen.
Es sieht so aus, als könnten diese die relevanten Formatdefinitionen sein.
Die relevanten Ausschnitte 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
Gute Frage.
Es scheint nicht viel im Internet darüber zu sein, aber ich habe das gefunden Native Dateispeichertypen (Zweite Tabelle nach unten), in der jeder native Dateispeichertyp und das, was er im entsprechenden Host -Datei -Datentyp aufgezeichnet wird, zeigt.
zB float = Sqlflt8
Real = Sqlflt4
Geld = Sqlmoney
numeric = sqlnumeric
Entschuldigung, wenn Sie bereits auf diese Liste gestoßen sind.