我一直在玩T,试图理解隐式转换和重载解析规则,但不知怎么的,它似乎有点奇怪……
上下文:
基本上,后者告诉您abs将在int、浮点、十进制等方面工作。因此,让我们看看它是如何工作的:
declare @foo2 sql_variant;
set @foo2 = abs(4);
select sql_variant_property(@foo2, 'BaseType')
-- result: int. OK, apparently we have an int overload. As expected.
declare @foo2 sql_variant;
set @foo2 = abs(cast(4.0 as float));
select sql_variant_property(@foo2, 'BaseType')
-- result: float. OK, apparently we have a float overload. As expected.现在,根据隐式类型转换表,我们可以隐式转换内容。我们将通过将var二进制转换为int来检查这一点,这应该根据类型优先规则进行:
declare @foo varbinary(4);
set @foo = cast(4 as varbinary(4));
select @foo + 2;
-- result: int. OK, as expected.从这一结果来看,我希望以下内容也能发挥作用:
declare @foo varbinary(4);
set @foo = cast(4 as varbinary(4));
select abs(@foo);
-- result: error: Operand type clash: varbinary is incompatible with float我不明白的东西(问题):
发布于 2016-01-28 12:24:05
来自MSDN的Abs:
Arguments
numeric_expression
Is an expression of the exact numeric or approximate numeric data type category.我猜想,调用Abs( varbinary )将尝试将var二进制转换为精确的数字或近似数字数据类型。
浮点数位于这些类型的数据类型优先级的顶部,所以我猜存在一个问题。
用我的逻辑更新
declare @foo varbinary(4);声明变量变量。
set @foo = cast( 4 as varbinary(4));通过执行从int到var二进制的显式强制转换,将一个值设置为此变量,这是完全可行的。
select sql_variant_property(@foo, 'BaseType')这表明变量是varbinary类型的。
select abs(@foo);尝试在var二进制文件上运行abs。错误信息是明确的:
Operand type clash: varbinary is incompatible with float因此,我的猜测是abs试图将varbinary隐式转换为中的第一个,以获得精确的数值或近似数字数据类型,即浮点数。
根据CAST and CONVERT图表,此转换失败。
发布于 2016-01-28 12:26:34
我希望我做得对!感谢你的评论。
您已经找到了转换和优先级MSDN页面,因此让我们来看看您的示例。
declare @foo varbinary(4);
set @foo = cast(4 as varbinary(4));福是什么类型的?
SELECT SQL_VARIANT_PROPERTY(@foo,'BaseType')
--------
varbinary到目前为止还不错。但在@foo里有什么?
SELECT @foo
----------
0x00000004现在,ABS()接受一个numeric --一个浮点数:

与4.00相比,4是什么样子的?让我们试试:
SELECT CONVERT(VARBINARY(MAX), 4.00) ,CONVERT(VARBINARY(MAX), 4);
------------------ -----------------------
0x0302000190010000 0x00000004看到4.00的内部表示与4不同吗?它存储的是精度、比例尺和值,而您的“int in a var二元”则不是。
这就是转换失败的原因。ABS()接受一个numeric,您的“错误格式”varbinary不能被胁迫到一个numeric,因为它不是一个,它是一些其他的表示--我们知道它表示一个int,但是Server没有。
如果要将浮点数添加到“在”变量二进制文件中的int中,则必须执行以下操作
select CONVERT(INT, @foo) + 2.0回到你的例子:
declare @foo varbinary(max);
set @foo = cast(4.00 as varbinary(max));
SELECT ABS(@foo+2.0)
----------
6.04.00以正确的内部格式转换为varbinary,并通过ABS()调用高兴地强制转换为numeric。快乐的日子。
https://stackoverflow.com/questions/35057532
复制相似问题