根据文档,可以使用以本机SQL Server数据格式格式化的bcp导入或导出本机(二进制)数据。这些示例包括SQLFLT8,SQLFLT4,SQLMONEY或SQLNUMERIC。
是否有人知道各种类型的数据格式是什么,或者可能找到指定这些格式的文档。例如,SQLFLT8是以IEEE双精度数或其他格式存储的吗?
编辑:从kevchadders和Andrew的答案中我有一点顿悟,为#define和typedef搜索了一下,看看我是否能找到C带有定义的头文件。这提出了一个文件odbcdss.h
;我在下面发布的answer有一些来自文件的输出,看起来很有希望。
答案 0 :(得分:5)
对于#define和typedef以及数据类型的一些进一步Google搜索结果显示此头文件(odbcss.h
)链接here.。第一行的#Defines用于魔术常量,它们直接对应于SQL数据类型的名称。下面的代码片段有一些typefs和struct定义,用于类型的敏感数据格式。
看起来这些可能是相关的格式定义。
相关的片段是:
// 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
答案 1 :(得分:4)
我不确定理论是否成立,但是可以使用一些SQL和一些搞清楚来找出类型的内部存储。我在我的博客上为新的datetime2 / datetimeoffset做了这个,以特别地获得内部二进制格式,因为我有兴趣看看它们是如何获得额外的准确性。
作为Money的一个例子
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作为值,理论上反转这个值只有1的十六进制应该是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
所以看起来它是一个带符号的8字节数字,因为它只是从FF等数字。使用-0.0001进行快速检查会发出所有0xFFF .... FFF符合预期,-0.0002给出0xFF .... FFE按预期进行。
这是否适用于BCP我不确定,但作为一种内部存储格式,我会猜测一个带有假定的4位小数的带符号的8字节整数。
答案 2 :(得分:1)
好问题。
网上似乎没有多少关于这一点,但我发现这个Native File Storage Types(第二个表格)显示了每个本机文件存储类型以及它在相应的主机文件数据类型中记录的内容。
e.g。
float = SQLFLT8
real = SQLFLT4
钱= SQLMONEY
numeric = SQLNUMERIC
如果您已经遇到此列表,请道歉。