SQL Server如何知道显示实际数据类型的准确度?

时间:2014-08-14 11:03:56

标签: 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

我得到以下结果:

[TimeID]     [Value1]     [CONV19,10]          [CONV19,3]        [CONV19,4]
12345        1126.089     1126.0885009766      1126.089          1126.0885

请注意,SQL Server Management Studio以其原始格式显示Value1到3个小数位(即,我没有将其转换)。

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

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

2 个答案:

答案 0 :(得分:0)

这不会回答你的问题但是会给你一个起点来自己回答吗?

首先阅读:

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

值得注意的是,“浮点数和实数的行为遵循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);

答案 1 :(得分:0)

如果是这种情况,我不知道,但是我怀疑SSMS正在使用.NET数字字符串格式。

我遇到了类似的情况,我只是想SELECT变成VARCHAR,就像SSMS在查询结果网格中显示的一样。

最后,我使用FORMAT使用了General format specifier函数。

例如:

DECLARE @Floats TABLE([FloatColumn] FLOAT);
INSERT INTO @Floats
VALUES
(123.4567),
(1.23E-7),
(PI());

SELECT
Number = f.FloatColumn,
Text = FORMAT(f.FloatColumn, 'G'),
IncorrectText = CONVERT(NVARCHAR(50), f.FloatColumn)
FROM @Floats f;

我必须给出一个免责声明,即我不知道这是否在所有情况下都可以正常工作,但是它可以满足我需要的一切。

我相信六年后这将非常有用。