Sql 在动态ORDER BY中将nvarchar转换为int时出错
SQL代码:Sql 在动态ORDER BY中将nvarchar转换为int时出错,sql,sql-server,Sql,Sql Server,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,16级,状态1,第3行 将nvarchar值“foo”转
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,16级,状态1,第3行
将nvarchar值“foo”转换为数据类型int时,转换失败
当我改为使用@SortOrder='id'时,它可以完美地工作。当我按名称进行正常的选择和排序时,它也能完美地工作
它为什么要尝试将nvarchar值转换为int数据类型,我如何阻止它这样做?
CASE
是一个返回特定数据类型的单个值的表达式。潜在值必须兼容,并且由于您必须具有名称值foo
,不能转换为INT
,因此会出现此错误。解决此问题的最简单方法是按数据类型将ORDER BY
表达式分开:
ORDER BY CASE @SortOrder WHEN 'id' THEN id END,
CASE @SortOrder WHEN 'name' THEN name END;
另一个备选方案(只要您启用了针对临时工作负载的优化功能,它可能更适合计划缓存)是动态SQL:
DECLARE @sql NVARCHAR(MAX) = N'SELECT ... ORDER BY ' + QUOTENAME(@SortOrder) + ';';
EXEC sp_executesql @sql;
也不确定为什么要为@SortOrder
指定最大数据类型-没有任何列名可以接近如此大的数据类型。通过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;
不,这一点都不管用。例如,9将在32之后排序。事实上,我刚刚发现了这个缺陷。我更喜欢选项1,因为:SET@SortOrder=N'1;删除表tblname;'@EdwardDortland当然,我不认为我们需要将整个动态SQL对话范围潜入其中。在性能更重要的地方,这些输入可能会受到足够的保护,希望执行用户一开始就没有DROP
权限-这是一个完全不同的问题。无论如何,QUOTENAME()
应该会有帮助。谢谢,这解决了它。