SQL Server存储过程中SELECT语句的ORDER BY子句中的IF语句

SQL Server存储过程中SELECT语句的ORDER BY子句中的IF语句,sql,sql-server,tsql,Sql,Sql Server,Tsql,我正在尝试创建一个存储过程,它接受一个位参数,如果真的按一列排序,如果假的按另一列排序。我将如何实现这一点 这是我到目前为止所拥有的 CREATE PROCEDURE [dbo].[CLICK10_GetCP] @switch AS BIT AS BEGIN SELECT acct_nbr, acct_name FROM acct ORDER BY

我正在尝试创建一个存储过程,它接受一个位参数,如果真的按一列排序,如果假的按另一列排序。我将如何实现这一点

这是我到目前为止所拥有的

CREATE PROCEDURE [dbo].[CLICK10_GetCP]
    @switch AS BIT
AS
    BEGIN
        SELECT
            acct_nbr,
            acct_name
        FROM
            acct
        ORDER BY 

    END
GO
简陋的方式:

IF @switch = 1
  BEGIN
    SELECT
            acct_nbr,
            acct_name
    FROM
            acct
    ORDER BY acct_nbr
  END
ELSE
  BEGIN
    SELECT
            acct_nbr,
            acct_name
    FROM
            acct
    ORDER BY acct_name
  END
您还应该能够使用用例..当我认为:

SELECT
  acct_nbr,
  acct_name
FROM
  acct
ORDER BY
  CASE @switch
    WHEN 1 THEN acct_nbr
    WHEN 0 THEN acct_name
  END

我不确定你能不能?我最终会这样做:

CREATE PROCEDURE [dbo].[CLICK10_GetCP]
    @switch AS BIT
AS
    BEGIN
        if @switch
        begin
            SELECT
                    acct_nbr,
                    acct_name
            FROM
                    acct
            ORDER BY 
                    acct_nbr
        end
        else
        begin
            SELECT
                    acct_nbr,
                    acct_name
            FROM
                    acct
            ORDER BY 
                    acct_name
        end
    END
GO

我想您可以将参数更改为int,然后按列按顺序排序:

CREATE PROCEDURE [dbo].[CLICK10_GetCP]
    @ordinal AS INT
AS
    BEGIN
        SELECT
                acct_nbr,
                acct_name
        FROM
                acct
        ORDER BY @Ordinal

    END
GO
这会抛出一个不错的错误(SQL2005):

Msg 1008,16级,状态1,第4行 所标识的选择项 ORDER BY number 1包含一个变量 作为表达式的一部分 列位置。变量只是 按表达式排序时允许 引用列名

谷歌搜索发现(SQL 2005及以上版本):


最简洁的方法是:

CREATE PROCEDURE [dbo].[CLICK10_GetCP]
    @switch AS BIT
AS
    BEGIN
        SELECT
                acct_nbr,
                acct_name
        FROM
                acct
        ORDER BY 
                case @switch
                    when 1 then acct_nbr
                    when 0 then acct_name
                end

    END
GO
这可能会导致较大表的执行计划不佳,或者如果acc nbr是int,acct name是varchar,则可能根本不起作用


在IF/ELSE语句中封装两个单独的查询对于较大的数据集可能会表现得更好,或者是在两列的数据类型不同的情况下唯一可行的方法

一种方法是建立如下查询:

CREATE PROCEDURE [dbo].[CLICK10_GetCP]
    @switch AS BIT
AS
DECLARE
@SQL nvarchar(max)


     SET @SQL N'SELECT
            acct_nbr,
            acct_name
    FROM
            acct
    ORDER BY '

if(@switch)
BEGIN
    @SQL = @SQL + ' acct_nbr '
END
ELSE
BEGIN 
    @SQL = @SQL + ' acct_Name '
END

Exec SP_ExecuteSQL @SQL

您可以通过在ORDER by中使用CASE语句来完成此操作,但如果查询足够复杂,则您的方法会更快。这仅在acct_nbr和acct_name具有相同的数据类型或可相互转换时才起作用。是的,但这是一种有用的技术。您可以将其作为一个CASE表达式编写。。。CASE当@switch=0然后Field1当@switch=1然后Field2 end如果每个CASE都有一个THEN子句,您不必担心字段是什么类型的。很抱歉,这确实像宣传的那样有效,所以+1。这(按大小写顺序@Switch WHEN 1 THEN Field1 ELSE Field2 END;)不起作用。
ORDER BY
   CASE WHEN @switch = 0 THEN Field1 END,
   CASE WHEN @Switch = 1 THEN Field2 END
CREATE PROCEDURE [dbo].[CLICK10_GetCP]
    @switch AS BIT
AS
    BEGIN
        SELECT
                acct_nbr,
                acct_name
        FROM
                acct
        ORDER BY 
                case @switch
                    when 1 then acct_nbr
                    when 0 then acct_name
                end

    END
GO
CREATE PROCEDURE [dbo].[CLICK10_GetCP]
    @switch AS BIT
AS
DECLARE
@SQL nvarchar(max)


     SET @SQL N'SELECT
            acct_nbr,
            acct_name
    FROM
            acct
    ORDER BY '

if(@switch)
BEGIN
    @SQL = @SQL + ' acct_nbr '
END
ELSE
BEGIN 
    @SQL = @SQL + ' acct_Name '
END

Exec SP_ExecuteSQL @SQL