忽略以下sql查询的实用性
DECLARE @limit BIGINT
SELECT TOP (COALESCE(@limit, 9223372036854775807))
*
FROM
sometable
警告
为TOP或FETCH子句行计数参数提供的行数必须是整数。
为什么它不起作用,但以下工作?
SELECT TOP 9223372036854775807
*
FROM
sometable
当COALESCE(@limit, 9223372036854775807)
为空时,9223372036854775807
确实是@limit
?
我知道将COALESCE
更改为ISNULL
有效,但我想知道原因。
答案 0 :(得分:2)
https://technet.microsoft.com/en-us/library/aa223927%28v=sql.80%29.aspx
指定bigint常量
超出int支持范围的整数常量 数据类型继续被解释为数字,标度为0和 足以保持指定值的精度。例如, 常量3000000000被解释为数字。这些数字常量 可隐式转换为bigint,可以分配给bigint 列和变量:
DECLARE @limit bigint
SELECT SQL_VARIANT_PROPERTY(COALESCE(@limit, 9223372036854775807),'BaseType')
SELECT SQL_VARIANT_PROPERTY(9223372036854775807, 'BaseType') BaseType
显示9223372036854775807为numeric
,因此合并的返回值为数字。而
DECLARE @limit bigint
SELECT SQL_VARIANT_PROPERTY(ISNULL(@limit, 9223372036854775807),'BaseType')
给出bigint
。差异为ISNULL
返回值具有第一个表达式的数据类型,但COALESCE
返回值具有最高的数据类型。
SELECT TOP (cast(COALESCE(@limit, 9223372036854775807) as bigint))
*
FROM
tbl
应该有用。
答案 1 :(得分:1)
DECLARE
@x AS VARCHAR(3) = NULL,
@y AS VARCHAR(10) = '1234567890';
SELECT
COALESCE(@x, @y) AS COALESCExy, COALESCE(@y, @x)
AS COALESCEyx,
ISNULL(@x, @y) AS ISNULLxy, ISNULL(@y, @x)
AS ISNULLyx;
输出:
COALESCExy COALESCEyx ISNULLxy ISNULLyx
---------- ---------- -------- ----------
1234567890 1234567890 123 1234567890
请注意,对于COALESCE,无论首先指定哪个输入,输出的类型都是VARCHAR(10) - 具有更高优先级的输出。但是,使用 ISNULL时,输出的类型由第一个输入决定。因此,当第一个输入是VARCHAR(3)数据类型(表达式别名为ISNULLxy)时,输出为VARCHAR(3)。结果,在输入@y中产生的返回值在三个字符后被截断。这意味着isnull不会改变类型,但是会合并。
答案 2 :(得分:1)
原来9223372036854775807是一个数字而不是bigint
来自https://technet.microsoft.com/en-us/library/aa223927(v=sql.80).aspx
超出int数据类型支持的范围的整数常量继续被解释为数字,标度为0,精度足以保存指定的值
所以我们需要明确地将它转换为bigint
DECLARE @limit BIGINT
SELECT TOP (COALESCE(@limit, CAST(9223372036854775807 AS BIGINT)))
*
FROM
sometable