Cad*_*oux 7 sql-server sql-server-2012
我有一个关于这个小提琴的问题:
DECLARE @TestVal AS float = 8.88;
SELECT flt = @TestVal
, xml = (SELECT Value = @TestVal FOR XML PATH(''), TYPE)
, fmt17 = FORMAT(@TestVal, 'G17')
, fmt = FORMAT(@TestVal, 'G')
, cst = CAST(@TestVal AS nvarchar(50))
, fmt17_roundtrip = CAST(FORMAT(@TestVal, 'G17') AS float)
, fmt_roundtrip = CAST(FORMAT(@TestVal, 'G') AS float)
, cst_roundtrip = CAST(CAST(@TestVal AS nvarchar(50)) AS float)
;
Run Code Online (Sandbox Code Playgroud)
https://dbfiddle.uk?rdbms=sqlserver_2019&fiddle=0cf05f882eb24f53e9484f043af99446
我在默认情况下以科学记数法输出某些 XML 时遇到了麻烦,虽然这些 XML 不正确或不准确,但可读性并不差。
我最初使用 FORMAT(floatcol, 'G17') 因为这个文档页面上的评论:
请注意,当与 Double 值一起使用时,“G17”格式说明符可确保原始 Double 值成功往返。这是因为 Double 是符合 IEEE 754-2008 标准的双精度 (binary64) 浮点数,可提供多达 17 位有效数字的精度。我们建议使用它而不是“R”格式说明符,因为在某些情况下,“R”无法成功地往返双精度浮点值。下面的例子说明了一种这样的情况。
好吧,今天我发现它似乎在字符串中添加了一些额外的无意义数字。在这个特定的例子中,它们都“往返”很好,但 G17 格式有一个额外的微不足道的数字。
尽管它可能不会影响我的往返行程,但我真的不想将它发送给具有额外数字的另一方。
现在我倾向于更改为 FORMAT('G'),但不确定其含义。目前,这些 XML 导出中使用的格式字符串是存储在我系统中的配置设置,因此继续使用 FORMAT 是最容易的,因为它不需要更改代码。
因此,在我对各种其他值进行测试之前,我的问题是 G 和 G17 之间的总体区别是什么,我可能会遇到使用 G 而不是 G17 的问题?
(是的,该值必须是浮点数,而不是小数或整数或货币,并且浮点数的域可能因不同的度量/上下文而异)。
系统确实需要在 2012 及更高版本上运行。
我的问题是总体上 G 和 G17 之间有什么区别,我可能会遇到使用 G 而不是 G17 的问题?
抱歉不知道,但你可以尝试用 XML 做一些事情。不确定这是否可以使用,但无论如何都在这里。
在处理类型化 XML 时,您将不会获得您的值的科学计数法,您将获得其他值的科学记数法。因此,使用类型化 XML 并将生成的 XML 分配给绑定到模式的 XML 变量,使用 xs:double 实现双精度。
这是一个架构。
create xml schema collection SC_F as '
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="F" type="xs:double">
</xs:element>
</xs:schema>
';
Run Code Online (Sandbox Code Playgroud)
以及使用架构的查询。
declare @TestVal float = 8.88;
declare @X xml(SC_F);
set @X = (select @TestVal as F for xml path(''), type);
select @X;
Run Code Online (Sandbox Code Playgroud)
结果:
<F>8.88</F>
Run Code Online (Sandbox Code Playgroud)
使用 XML 修复它的另一种方法是将浮点值转换为 XML,然后将 XML 用作 XML 查询的值。现在听起来比实际复杂,我希望。
declare @TestVal float = 8.88;
select cast('' as xml).query('sql:variable("@TestVal")');
Run Code Online (Sandbox Code Playgroud)
结果
8.88
Run Code Online (Sandbox Code Playgroud)
下面是一些代码,显示了不同解决方案的不同输出。根据值,您最终将获得所有方法的科学记数法。
declare @T table(F float not null);
insert into @T(F) values(8.88),(0),(0.0001),(0.00001),(0.000001),
(0.0000001),(0.84551240822557006);
declare @X1 xml;
declare @X2 xml(SC_F);
declare @X3 xml;
declare @X4 xml;
declare @X5 xml;
set @X1 = (select F from @T for xml path(''));
set @X2 = (select F from @T for xml path(''));
set @X3 = (select cast('' as xml).query('sql:column("F")') as F from @T for xml path(''));
set @X4 = (select format(F, 'G') as F from @T for xml path(''));
set @X5 = (select format(F, 'G17') as F from @T for xml path(''));
select @X1 as ScienceAllTheWay,
@X2 as UsingASchema,
@X3 as XMLTrickery,
@X4 as FormatG,
@X5 as FormatG17;
Run Code Online (Sandbox Code Playgroud)
结果:
科学一路
<F>8.880000000000001e+000</F>
<F>0.000000000000000e+000</F>
<F>1.000000000000000e-004</F>
<F>1.000000000000000e-005</F>
<F>1.000000000000000e-006</F>
<F>1.000000000000000e-007</F>
<F>8.455124082255701e-001</F>
Run Code Online (Sandbox Code Playgroud)
使用架构
<F>8.88</F>
<F>0</F>
<F>0.0001</F>
<F>1E-05</F>
<F>1E-06</F>
<F>1E-07</F>
<F>0.84551240822557006</F>
Run Code Online (Sandbox Code Playgroud)
XML技巧
<F>8.88</F>
<F>0.0E0</F>
<F>0.0001</F>
<F>0.00001</F>
<F>0.000001</F>
<F>1.0E-7</F>
<F>0.84551240822557</F>
Run Code Online (Sandbox Code Playgroud)
格式G
<F>8.88</F>
<F>0</F>
<F>0.0001</F>
<F>1E-05</F>
<F>1E-06</F>
<F>1E-07</F>
<F>0.84551240822557</F>
Run Code Online (Sandbox Code Playgroud)
格式G17
<F>8.8800000000000008</F>
<F>0</F>
<F>0.0001</F>
<F>1.0000000000000001E-05</F>
<F>9.9999999999999995E-07</F>
<F>9.9999999999999995E-08</F>
<F>0.84551240822557006</F>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
141 次 |
最近记录: |