在公共新闻组中,一个经常出现的问题是“怎样才能根据传递给存储过程的参数返回一个排序的输出?”。在一些高水平专家的帮助之下,我整理出了这个问题的几种解决方案。
一、用IF...ELSE执行预先编写好的查询
对于大多数人来说,首先想到的做法也许是:通过IF...ELSE语句,执行几个预先编写好的查询中的一个。例如,假设要从Northwind数据库查询得到一个货主(Shipper)的排序列表,发出调用的代码以存储过程参数的形式指定一个列,存储过程根据这个列排序输出结果。Listing 1显示了这种存储过程的一个可能的实现(GetSortedShippers存储过程)。
【Listing 1: 用IF...ELSE执行多个预先编写好的查询中的一个】
CREATE PROC GetSortedShippers
@OrdSeq AS int
AS
IF @OrdSeq = 1
SELECT * FROM Shippers ORDER BY ShipperID
ELSE IF @OrdSeq = 2
SELECT * FROM Shippers ORDER BY CompanyName
ELSE IF @OrdSeq = 3
SELECT * FROM Shippers ORDER BY Phone
这种方法的优点是代码很简单、很容易理解,SQL Server的查询优化器能够为每一个SELECT查询创建一个查询优化计划,确保代码具有最优的性能。这种方法最主要的缺点是,如果查询的要求发生了改变,你必须修改多个独立的SELECT查询——在这里是三个。
二、用列名字作为参数
另外一个选择是让查询以参数的形式接收一个列名字。Listing 2显示了修改后的GetSortedShippers存储过程。CASE表达式根据接收到的参数,确定SQL Server在ORDER BY子句中使用哪一个列值。注意,ORDER BY子句中的表达式并未在SELECT清单中出现。在ANSI SQL-92标准中,ORDER BY子句中不允许出现没有在SELECT清单中指定的表达式,但ANSI SQL-99标准允许。SQL Server一直允许这种用法。
【Listing 2:用列名字作为参数,第一次尝试】
CREATE PROC GetSortedShippers
@ColName AS sysname
AS
SELECT *
FROM Shippers
ORDER BY
CASE @ColName
WHEN 'ShipperID' THEN ShipperID
WHEN 'CompanyName' THEN CompanyName
WHEN 'Phone' THEN Phone
ELSE NULL
END
现在,我们来试一下新的存储过程,以参数的形式指定ShipperID列:
EXEC GetSortedShippers 'ShipperID'
此时一切正常。但是,当我们视图把CompanyName列作为参数调用存储过程时,它不再有效:
EXEC GetSortedShippers 'CompanyName'
仔细看一下错误信息:
Server: Msg 245, Level 16, State 1, Procedure GetSortedShippers, Line 5
Syntax error converting the nvarchar value 'Speedy
Express' to a column of data type int.
它显示出,SQL Server试图把“Speedy Express”(nvarchar数据类型)转换成一个整数值——当然,这个
数据库查询结果的动态排序
最新推荐文章于 2024-01-16 10:34:42 发布
本文探讨了如何在SQL Server中根据存储过程参数实现动态排序查询。通过IF...ELSE、列名作为参数、动态执行SQL语句以及使用用户定义函数(UDF)等方法,解决在不同场景下对查询结果进行排序的问题。文中详细展示了每种方法的实现代码,并分析了其优缺点和适用情况。
摘要由CSDN通过智能技术生成