Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 为什么在这个COALESCE语句中会发生这种隐式类型转换?_Sql Server_Database_Types_Sqldatatypes - Fatal编程技术网

Sql server 为什么在这个COALESCE语句中会发生这种隐式类型转换?

Sql server 为什么在这个COALESCE语句中会发生这种隐式类型转换?,sql-server,database,types,sqldatatypes,Sql Server,Database,Types,Sqldatatypes,为什么这里的天花()会将数据类型更改为(38,0),从而丢失小数点后的精度 这只发生在十进制(38,X)中,如下所示 在Microsoft SQL Server 2016上运行 DECLARE @decimal2 DECIMAL(37,4) = 1.1 SELECT COALESCE(1.1,CEILING(@decimal2)) ^这返回1.1 DECLARE @decimal DECIMAL(38,4) = 1.1 SELECT COALESCE(1.1,CEILING(@decimal

为什么这里的天花()会将数据类型更改为(38,0),从而丢失小数点后的精度

这只发生在十进制(38,X)中,如下所示

在Microsoft SQL Server 2016上运行

DECLARE @decimal2 DECIMAL(37,4) = 1.1
SELECT COALESCE(1.1,CEILING(@decimal2)) 
^这返回1.1

DECLARE @decimal DECIMAL(38,4) = 1.1
SELECT COALESCE(1.1,CEILING(@decimal))
^这个返回1

返回一个整数,但它应该是传入的数据类型。我不知道示例中为什么会出现这个问题,但您可以这样克服它:

DECLARE @decimal DECIMAL(38,4) = 1.1
SELECT COALESCE(@decimal,CEILING(@decimal)) --RETURNS 1
SELECT COALESCE(@decimal,CAST(CEILING(@decimal) AS DECIMAL(38,4))) --RETURNS 1.1000
我避免这些类型问题的规则是始终将不同的数据类型强制转换为一个公共数据类型。

这一行为在Microsoft Docs的文章中(令人困惑地)进行了解释。 这是文章的摘录:

结果精度和刻度绝对最大值为38。当结果精度大于38时,它将减少到38,并减少相应的比例,以防止截断结果的整数部分


现在,令人困惑的部分是理解如何计算精度和比例。根据我的测试,它似乎使用了加法规则。对于精度
max(s1,s2)+max(p1-s1,p2-s2)+1
和比例
max(s1,s2)
。但由于精度超过38,从刻度中提取差异以保持整数部分的完整性。

这仅仅是因为数字数据类型只能容纳38位,并且将首先填充最重要的值,因此,如果您说37,4,它将填充小数点左边的37位,并保留右边的一位。
如果你把38放在小数点的左边,那么不管你把什么放在右边,都没有小数点的空间。

为什么你在这里也用
COALESCE
来包装呢?嗯,可能是因为当你把像999999999999999999999999999999999999这样的东西放进去时(前面37位,后面一位),结果是100000000000000000000000000000,您需要额外的数字来防止溢出。@larnu,这只是一段测试代码,它代表了一段更复杂的代码。这是解决问题的最简单的方法——当选择了具有最高优先级的合并数据类型时,这里的数据类型是decimal(38,0),这切断了我们的精度。@stickybit,这很有意义。。没有上限实际返回传入的相同数据类型。编辑(可能这不太正确——请参阅文档)“天花板返回一个整数数据类型。”——否则表示:“返回值的类型与数值_表达式(输入;注释:me)相同。”@EvanCS添加了一个指向文档的链接抱歉,我没有在文档下方看到该注释。我读了这篇“这个函数返回最小的大整数”,没有继续读下去,不用担心!另外,FWIW,这很容易“修复”,我只是对这种行为感到好奇。