在运行此查询时,我收到错误,任何想法为什么?
select ISNULL(NULLIF(0,0), -1)
错误:
Msg 220,Level 16,State 2,Line 1
数据类型tinyint的算术溢出错误,值= -1。
编辑 - 另一个例子:
select ISNULL(NULLIF(0.0,0.0), 1.0)
Msg 8115,Level 16,State 8,Line 1 算术溢出错误将数字转换为数据类型数字。
答案 0 :(得分:5)
这项工作:
select ISNULL(NULLIF(cast(0 as int),0), -1)
SQL优化器做"隐藏"转换为最小的数据类型。
来自NULLIF(http://technet.microsoft.com/pl-pl/library/ms177562%28v=sql.110%29.aspx)的文档:
返回与第一个表达式相同的类型。
所以NULLIF返回tinyint,ISNULL尝试将tinyint替换为-1然后你有溢出
当你将第一个参数(0)转换为int(或smallint)时,NULLIF会返回你的" new"数据类型,适用于-1
要查找正在使用的实际类型:
SELECT NULLIF(0,0) test_col INTO #test_table
SELECT data_type, numeric_precision, numeric_scale
FROM tempdb.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE '#test_table%' AND COLUMN_NAME = 'test_col'
答案 1 :(得分:1)
无论如何,这都是奇怪的行为。为什么像“0”这样的常量以不同的方式计算 - 有时是 int 有时是 tinyint。如果我做 SELECT 选择一个常量“0”,那么它被评估为“int”。但是将“0”传递给 NULLIF() 常量被评估为 tinyint。并且在 NULLIF 文档中根本没有提到这种行为。
-- 1) SELECT evaluates numeric constant "0" as "int":
DROP TABLE IF EXISTS #t
GO
SELECT c = 0
INTO #t
GO
EXEC tempdb..sp_help #t
GO
-- 2) NULLIF() evaluates numeric constant "0" as "tynyint":
DROP TABLE IF EXISTS #t
GO
SELECT c = NULLIF(0, 0)
INTO #t
GO
EXEC tempdb..sp_help #t
GO