【发布时间】:2019-09-09 18:48:40
【问题描述】:
我们正在尝试将 SAS7BDAT 文件导入 SQL Server 数据库。 我们遇到的唯一问题是源十进制值被读取为浮点数。
使用名为 dsread 的命令行工具,我们找到了一个选项:
将 SAS7BDAT 文件中的 IEEE 浮点数值转换为其十进制表示可能会导致精度损失。要获得数据的无损表示,请使用 /l 标志:
sashelp> dsread /v /l prdsale
ACTUAL,PREDICT,COUNTRY,...
0x0000000000e88c40,0x0000000000908a40,CANADA...
0x0000000000388f40,0x0000000000907240,CANADA...
0x0000000000008340,0x0000000000708a40,CANADA...
0x0000000000108440,0x0000000000a88040,CANADA...
0x0000000000808440,0x0000000000308440,CANADA...
0x0000000000a08d40,0x0000000000607e40,CANADA...
...etc...
数字输出为 8 个十六进制字节(16 位),给出内部浮点表示,然后可用于在接收软件中重建完全相同的值。使用 /L 以大端顺序获取字节
运行一些测试,当我们使用 /L 标志时,我们可以看到十进制值 -1.457263 由值 0xcbbbea01f350f7bf 表示。我们一直想不通的是,如何将十六进制值转换为 SQL Server 十进制值?
我们尝试了许多变体,包括:
select CONVERT(decimal, convert(varbinary,'0xcbbbea01f350f7bf',1))
但这会导致:
消息 8115,第 16 级,状态 6,第 17 行
将 varbinary 转换为数字数据类型时出现算术溢出错误。
【问题讨论】:
-
您需要从文件中提供的二进制表示中“计算”十进制值。为此,您需要了解如何在示例中读取十六进制值的逻辑,然后将其转换为适当的十进制值。如果你不能在纸上做到这一点,你就不能真正期望编写代码来做到这一点。您需要了解一件事的字节序。
-
再试一次 - 如果您通过将数字转换为字符串来导出数字,可能会更容易导入
-
感谢您的反馈,斯莫尔。我们也尝试将数据作为字符串导入。我们看到像 7.771561e-16 这样的指数值。我们已经获得了文件中两个数值的汇总数字,但我们无法完全匹配它们,因为这两列一直被解释为来自源的浮点值。显然,使用 /L 标志的数据输出是大端顺序。我会研究这意味着什么。
标签: sql sql-server hex