为什么 SQL Server 将浮点数转换为科学记数法?

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)

但整件事让我摸不着头脑。

问题:以这种方式存储它们的浮点数是怎么回事?

Pau*_*ite 6

记录CAST和下CONVERT

对于floatreal 表达式样式可以具有下表中显示的值之一。其他值处理为 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。您的浮点数都超过六位,因此它们以科学记数法表示

浮点数通常以科学记数法显示。当范围比绝对精度更重要时使用这些类型。这些数字在其他格式中很快变得笨拙。科学记数法也有助于强调有限的精度。

您可能喜欢使用STRFORMAT代替:

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 之间的整数。