SQL Server 如何知道显示真实数据类型的精度?

Qua*_*eek 5 sql sql-server formatting

我正在尝试将远程 SQL 2000 数据库中的表复制到本地 SQL 2012 实例中。

作为检查已更改值的快速方法,我使用了Simple Talk 中的“UNION ALL...GROUP BY”技术(向下滚动大约一半)。

不幸的是,远程数据类型被设置为 REAL,因为这是一种近似数据类型,这不是很可靠,因为它会在我不希望的地方找到差异(即使这些差异在计算上存在)。

我曾尝试使用 CONVERT 将值更改为 NUMERIC(精确)数据类型。然而,不同的列有不同的小数位数,找到一个适合所有的解决方案被证明是困难的。

我注意到的一件事是,如果我运行以下查询(TimeID 是一个 INT,而 Value1 是一个 REAL):

SELECT [TimeID], [Value1], CONVERT(DECIMAL(19,10), [Value1]) AS [CONV19,10], CONVERT(DECIMAL(19,3), [Value1]) AS [CONV19,3], CONVERT(DECIMAL(19,4), [Value1]) AS [CONV19,4]
FROM   [DATABASE].[SCHEMA].[TABLE]
WHERE  [TimeID] = 12345
Run Code Online (Sandbox Code Playgroud)

我得到以下结果:

[TimeID]     [Value1]     [CONV19,10]          [CONV19,3]        [CONV19,4]
12345        1126.089     1126.0885009766      1126.089          1126.0885
Run Code Online (Sandbox Code Playgroud)

请注意,SQL Server Management Studio 在其本机格式(即没有我转换它)时将 Value1 显示为 3 个小数位。

所以我的问题是:SSMS 如何知道它应该显示到小数点后 3 位?它怎么知道 1126.0885 不是实际存储的数字,而是 1126.089?

理想情况下,我想了解它的算法,以便我可以复制它以将我的数据转换为正确的小数位数。

Ric*_*ell 0

这不会回答您的问题,但会给您一个自己回答问题的起点?

首先读一下这个:

http://msdn.microsoft.com/en-us/library/ms187912.aspx

值得注意的是,“float 和 real 的行为遵循近似数字数据类型的 IEEE 754 规范。”

现在读一下:

http://en.wikipedia.org/wiki/IEEE_floating_point

所以现在你应该知道浮点数/实数是如何存储的以及为什么它们是“近似”数字。

至于 SSMS 如何“知道”实数/浮点数有多少位小数,我真的不知道,但这与 IEEE 754 规范有关?

演示这一点的简单脚本是:

DECLARE @MyNumber FLOAT(24) = 1.2345;
SELECT @MyNumber, CONVERT(NUMERIC(19, 4), @MyNumber), CONVERT(NUMERIC(19, 10), @MyNumber), CONVERT(NUMERIC(19, 14), @MyNumber);
Run Code Online (Sandbox Code Playgroud)