SQL代码:
DECLARE @SortOrder nvarchar(max);
SET @SortOrder = 'name';
SELECT * FROM [database_name].[schema_name].[table_name]
ORDER BY CASE @SortOrder
WHEN 'id' THEN id
WHEN 'name' THEN name
END;
输出: Msg 245,Level 16,State 1,Line 3 将nvarchar值'foo'转换为数据类型int时,转换失败。
当我改为使用@SortOrder ='id'时,它完美无缺。当我做一个普通的SELECT和ORDER BY名称时,它也可以完美地运行。
为什么会尝试将nvarchar值转换为数据类型int,如何阻止它这样做呢?
答案 0 :(得分:9)
CASE
是一个表达式,它返回特定数据类型的单个值。潜在值必须兼容,并且由于您必须具有foo
的名称值(无法转换为INT
),因此会出现此错误。解决此问题的最简单方法是按数据类型分隔ORDER BY
表达式:
ORDER BY CASE @SortOrder WHEN 'id' THEN id END,
CASE @SortOrder WHEN 'name' THEN name END;
另一种替代方案(对于计划缓存可能更好,只要你有optimize for ad hoc workloads
)就是动态SQL:
DECLARE @sql NVARCHAR(MAX) = N'SELECT ... ORDER BY ' + QUOTENAME(@SortOrder) + ';';
EXEC sp_executesql @sql;
也不确定为什么要给你的@SortOrder
最大数据类型 - 没有列名可能在那么大的附近。
答案 1 :(得分:-2)
通过case语句的所有路由必须输出相同的数据类型。尝试将ID转换为这样的字符串,它将起作用。
DECLARE @SortOrder nvarchar(max);
SET @SortOrder = 'name';
SELECT * FROM [database_name].[schema_name].[table_name]
ORDER BY CASE @SortOrder
WHEN 'id' THEN cast(id AS NVARCHAR(20))
WHEN 'name' THEN name
END;