【发布时间】:2012-07-02 15:54:24
【问题描述】:
根据MSDN,REAL 值的范围是 - 3.40E + 38 到 -1.18E - 38、0 和 1.18E - 38 到 3.40E + 38。但是,我有很多超出该范围的值在我的桌子上。
以下查询返回许多非常小的值,而没有非常大的值:
SELECT MyColumn ,
*
FROM data.MyTable
WHERE MyColumn <> 0
AND ( MyColumn < CONVERT(REAL, 1.18E-38)
OR MyColumn > CONVERT(REAL, 3.40E+38)
)
AND ( MyColumn < CONVERT(REAL, -3.40E+38)
OR MyColumn > CONVERT(REAL, -1.18E-38)
)
很容易显示这些值如何最终出现在表格中。我不能直接插入它们:
CREATE TABLE a(r REAL NULL);
GO
INSERT INTO a(r) VALUES(4.330473E-39);
GO
SELECT r FROM a
GO
DROP TABLE a;
----
0.0
但我可以将两列分开并得到和超出范围值:
CREATE TABLE a
(
r1 REAL NULL ,
r2 REAL NULL ,
r3 REAL NULL
) ;
GO
INSERT INTO a
( r1, r2 )
VALUES ( 4.330473E-38, 1000 ) ;
GO
UPDATE a
SET r3 = r1 / r2 ;
SELECT r1 ,
r2 ,
r3
FROM a
r1 r2 r3
------------- ------------- -------------
4.330473E-38 1000 4.330433E-41
所以我猜 MSDN 给出了错误的有效数据范围,对吗? 我错过了什么吗?
一些人认为这是一个错误。
这种行为的哪一部分是错误。是吗:
- MSDN 中记录并在 DBCC 中使用的常量错误,以及向下舍入的错误阈值。
- 更新可以保存错误的值
【问题讨论】:
-
好像是个bug,你把它归档到你最喜欢的地方了吗?我想您可以添加自己的约束,例如
CHECK (r3 > 3.40E-38):-) -
@AaronBertrand 我绝对可以添加一个约束,但我想了解为什么 SQL Server 的行为不像记录的那样。
-
dbcc checktable('a') with DATA_PURITY:列“r3”值超出数据类型“real”的范围。将列更新为合法值。举报... -
正如我所说,这似乎是一个错误。 :-)
-
其实它看起来不像是一个错误。一旦检查并启用了 DATA_PURITY,就不会再发生这种情况了。
标签: sql-server sql-server-2008 sql-server-2008-r2 data-integrity