Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在动态ORDER BY中将nvarchar转换为int时出错_Sql_Sql Server - Fatal编程技术网

Sql 在动态ORDER BY中将nvarchar转换为int时出错

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”转

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”转换为数据类型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()
应该会有帮助。谢谢,这解决了它。