ما هي تنسيقات التخزين الثنائية لـ SQFLT8 و SQLMoney وأنواع بيانات SQL الأصلية الأخرى؟
-
21-09-2019 - |
سؤال
وفقًا للوثائق ، يمكن استيراد أو تصدير البيانات الأصلية (الثنائية) باستخدام تنسيق BCP في تنسيقات بيانات خادم SQL الأصلية. أمثلة على هذه هي SQLFLT8 أو SQLFLT4 أو SQLMoney أو SQLNUMeric.
هل يعرف أي شخص إما تنسيقات البيانات للأنواع المختلفة ، أو حيث يمكن العثور على وثائق تحدد هذه التنسيقات. على سبيل المثال ، هل يتم تخزين SQLFLT8 كرقم دقيق لـ IEEE أو بتنسيق آخر؟
يحرر: من الإجابات Kevchadders و أندرو كان لدي القليل من عيد الغطاس فعل القليل من googling لـ #define و typedef لمعرفة ما إذا كان بإمكاني العثور على ملفات C مع تعريفات. جاء هذا بملف odbcdss.h
; ؛ ال إجابه لقد نشرت أدناه لديه بعض الأدوات الخارجية من الملف ، والذي يبدو واعداً للغاية.
المحلول
لست متأكدًا مما إذا كانت النظرية ستحتفظ ، ولكن يمكن تحقيق التخزين الداخلي للأنواع باستخدام بعض SQL وقليلًا من اكتشافها. لقد فعلت ذلك من أجل DateTime2 / DateTimeOffset على مدونتي للحصول على التنسيق الثنائي الداخلي لأنني كنت مهتمًا برؤية كيف حصلوا على الدقة الإضافية.
كمثال على المال
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
الإخراج: 0x000000000001e208
هذا هو 123400 عند اعتباره رقمًا عشريًا ، يتم تخزين الأموال إلى 4 أماكن عشرية بحيث تشير إلى 12.3400 كقيمة ، مما يعكس هذا من الناحية النظرية قيمة واحدة فقط في Hex هي 0.0001
declare @test money
declare @binaryValue binary(8)
set @binaryvalue = 0x0000000000000001
set @test = convert(money,@binaryvalue)
select @test
مخرجات 0.0001
الشيء التالي الذي أود التحقق منه هو الأرقام السلبية ،
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
الإخراج: 0xfffffffffffe1df8
بحيث يبدو أنه رقم بايت موقّع ، لأنه يأخذ الرقم بعيدًا عن FF ... إلخ. يؤدي فحص سريع مع -0.0001 إلى إعطاء جميع 0xFFF .... FFF كما هو متوقع و -0.0002 يعطي 0xFF .... FFE كما هو متوقع.
ما إذا كان هذا يسير على BCP ، لست متأكدًا ، لكن كتنسيق تخزين داخلي ، سأخمن في عدد صحيح موقّع 8 بايت يحتوي على 4 أماكن عشرية مفترضة.
نصائح أخرى
بعض googling آخر لـ #define و typedef بالاقتران مع أنواع البيانات التي أظهرت ملف الرأس هذا (odbcss.h
) مرتبط هنا.. يحتوي السطر الأول على #Defines للثوابت السحرية التي تتوافق مباشرة مع أسماء أنواع بيانات SQL. يحتوي المقتطف السفلي على بعض الأوعية والتعريفات الهيكلية لتنسيقات البيانات المعقولة للأنواع.
يبدو أن هذه يمكن أن تكون تعريفات التنسيق ذات الصلة.
المقتطفات ذات الصلة هي:
// 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
سؤال جيد.
لا يبدو كثيرًا على شبكة الإنترنت حول هذا ولكن وجدت هذا أنواع تخزين الملفات الأصلية (الجدول الثاني لأسفل) الذي يوضح كل نوع تخزين الملف الأصلي وما يتم تسجيله في نوع بيانات ملف المضيف المقابل.
مثل التعويم = sqlflt8
حقيقي = sqlflt4
المال = sqlmoney
رقمي = sqlnumeric
الاعتذار إذا كنت قد واجهت هذه القائمة بالفعل.