【问题标题】:What are the binary storage formats for sqflt8, sqlmoney and other native SQL data types?sqflt8、sqlmoney等原生SQL数据类型的二进制存储格式有哪些?
【发布时间】:2011-01-07 04:19:55
【问题描述】:

根据文档,可以使用原生 SQL Server 数据格式格式化的 bcp 导入或导出原生(二进制)数据。这些示例包括 SQLFLT8、SQLFLT4、SQLMONEY 或 SQLNUMERIC。

有谁知道各种类型的数据格式是什么,或者在哪里可以找到指定这些格式的文档。例如,SQLFLT8 是存储为 IEEE 双精度数还是其他格式?

编辑:根据kevchaddersAndrew 的回答,我有点顿悟,我在谷歌上搜索了一些#define 和typedef,看看是否能找到带有定义的C 头文件.这提出了一个文件odbcdss.h;我在下面发布的answer 有一些从文件中提取的内容,看起来很有希望。

【问题讨论】:

    标签: sql-server file-format bcp


    【解决方案1】:

    我不确定这个理论是否成立,但是可以使用一些 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 作为值,反过来,理论上只有 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,但作为一种内部存储格式,我会猜测一个有符号的 8 字节整数,假设有 4 个小数位。

    【讨论】:

    • bcp 的文档确实暗示“本机”格式与 SQL Server 中数据的本机表示相同,但​​没有明确记录格式。一些进一步的搜索发现了一个 C 头文件,其中包含与数据类型相对应的各种类型定义,看起来很合理。 +1 用于(a)考虑在 SQL Server 中转换为 binary() 数据类型 - 我没有想到 - 和(b) 麻烦测试假设。很好的答案。
    • 该文件中的 Datetime 定义是正确的,低 4 个字节是 300 分之一秒的无符号数,我在执行 datetime2 以显示差异时也对其进行了解码。跨度>
    【解决方案2】:

    进一步搜索#define 和 typedef 以及数据类型,发现这个头文件 (odbcss.h) 链接 here.。第一行为与 SQL 数据类型名称直接对应的魔术常量提供了#Defines。较低的 sn-p 具有一些 typefs 和 struct 定义,用于这些类型的外观数据格式。

    看起来这些可能是相关的格式定义。

    相关的sn-ps是:

    // 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
    

    【讨论】:

      【解决方案3】:

      好问题。

      网上似乎没有太多关于此的内容,但我发现了这个Native File Storage Types(第二个表格),它显示了每个本机文件存储类型以及它在相应的主机文件数据类型中记录的内容。

      例如 浮动 = SQLFLT8
      实数 = SQLFLT4
      钱 = SQLMONEY
      数字 = SQLNUMERIC

      如果您已经看到此列表,我们深表歉意。

      【讨论】:

      • 我已经看过这个,以及其他类似的材料。尽管此材料有时会提到它,但它并没有真正出来并说明这些是否是机器原生格式。一些额外的谷歌搜索出现了我在编辑中放入的 c 头文件,它看起来非常像类型的类型定义。见下文。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      • 2021-06-13
      • 1970-01-01
      • 2010-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多