Jam*_*mes -1 sql-server floating-point number-formatting
我遇到了一些奇怪的行为:在将浮点值传递到 varchar 列时,这些值正在从整数转换为科学记数法,而正是这种科学记数法存储为字符串。
if OBJECT_Id('tempdb..#whydis') is not null begin drop table #whydis end
if OBJECT_Id('tempdb..#ImSeriously') is not null begin drop table #ImSeriously end
create table #whydis (bigID float)
create table #ImSeriously (bigID varchar(255))
insert into #whydis(BigID)
values(1495591),
(1495289),
(1495610),
(1495611),
(1495609),
(1495592),
(1495686)
INSERT INTO #ImSeriously (bigID)
SELECT BigID from #whydis
select * from #ImSeriously
Run Code Online (Sandbox Code Playgroud)
结果如下所示:
1.49559e+006
以字符串形式存储的科学记数法。通过转换为 int 很容易解决:
INSERT INTO #ImSeriously (bigID)
SELECT cast(BigID as int) from #whydis
Run Code Online (Sandbox Code Playgroud)
但整件事让我摸不着头脑。
问题:以这种方式存储它们的浮点数是怎么回事?
这记录在CAST和下CONVERT:
对于float或real 表达式,样式可以具有下表中显示的值之一。其他值处理为 0。
| 价值 | 输出 |
|---|---|
| 0(默认) | 最多 6 位数字。适当时使用科学记数法。 |
| 1 | 始终为 8 位数字。始终使用科学记数法。 |
| 2 | 总是 16 位数字。始终使用科学记数法。 |
| 3 | 始终为 17 位数字。用于无损转换。使用这种样式,可以保证每个不同的浮点数或实数都转换为不同的字符串。 适用于:SQL Server(从 SQL Server 2016 (13.x) 开始)和 Azure SQL 数据库。 |
| 126, 128, 129 | 出于遗留原因包括在内;未来的版本可能会弃用这些值。 |
您正在使用从 float 到 varchar(255) 的隐式转换,它隐式使用样式 0。您的浮点数都超过六位,因此它们以科学记数法表示。
浮点数通常以科学记数法显示。当范围比绝对精度更重要时使用这些类型。这些数字在其他格式中很快变得笨拙。科学记数法也有助于强调有限的精度。
DECLARE @f float;
SET @f = 123456789012345e294;
SELECT
LTRIM(STR(@f, 309, 0)),
FORMAT(@f, 'F0');
Run Code Online (Sandbox Code Playgroud)
两者都产生输出:
DECLARE @f float;
SET @f = 123456789012345e294;
SELECT
LTRIM(STR(@f, 309, 0)),
FORMAT(@f, 'F0');
Run Code Online (Sandbox Code Playgroud)
对于float,可以精确表示从 ?2 53到 2 53 (?9,007,199,254,740,992 到 9,007,199,254,740,992) 的整数。对于real,可以精确表示 ?16777216 和 16777216 之间的整数。