Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.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 Server中带变量的分页排序_Sql_Sql Server 2008 - Fatal编程技术网

SQL Server中带变量的分页排序

SQL Server中带变量的分页排序,sql,sql-server-2008,Sql,Sql Server 2008,此SQL语句在SQL Server中的标记顺序为'+@SortField+'+@SortOrder+'部分。。有什么好主意吗?我怎么修 ALTER PROC [sbuser].[sp_MemberMailList ] @MemberMailID bigint = null, @FromMemberID bigint = null, @ToMemberID bigint = null, @Subject varchar(150) = null, @Message varchar(8000) = n

此SQL语句在SQL Server中的标记顺序为'+@SortField+'+@SortOrder+'部分。。有什么好主意吗?我怎么修

ALTER PROC [sbuser].[sp_MemberMailList ]
@MemberMailID bigint = null,
@FromMemberID bigint = null,
@ToMemberID bigint = null,
@Subject varchar(150) = null,
@Message varchar(8000) = null,
@FromDeletedFlag bit = null,
@ToDeletedFlag bit = null,
@FromArchivedFlag bit = null,
@ToArchivedFlag bit = null,
@ReadFlag bit = null,
@SQL nvarchar(4000) = null,
@SortField varchar(100) = null,
@SortOrder varchar(25) = null,
@NotificationSent bit = null,
@MemberID bigint = null,
@OnHold bit = 0,
@SpecialMail varchar(1) = 'N',
@PageSize float = null,
@PageNum int = 1,
@TotalPages float = null,
@StartDate datetime = null,
@EndDate datetime = null,
@MODE varchar(50)

AS

IF @MODE = 'INBOX-MAIL'
BEGIN
    SELECT @TotalPages = COUNT(*)/@PageSize
    FROM MemberMail a
    INNER JOIN Member b ON b.MemberID = a.FromMemberID
    WHERE a.ToMemberID = @ToMemberID
    AND a.ToDeletedFlag = 0
    AND a.OnHold = 0
    AND a.ToArchivedFlag = 0;

    WITH InMails AS
    (
        SELECT ROW_NUMBER() OVER(ORDER BY ' + @SortField + ' ' + @SortOrder + ') AS RowNum,
        a.MemberMailID,
        a.FromMemberID,
        a.Subject,
        a.CreateDate,
        b.UserName,
        a.ToReadFlag,
        b.Firstname,
        b.Lastname,
        b.MemberDisplayName AS DisplayName
        FROM MemberMail a
        INNER JOIN Member b ON b.MemberID = a.FromMemberID
        WHERE a.ToMemberID = @ToMemberID
        AND a.ToDeletedFlag = 0
        AND a.OnHold = 0
        AND a.ToArchivedFlag = 0
    )
    SELECT * 
    FROM InMails
    WHERE RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize
    ORDER BY CreateDate DESC
END
任何帮助都将不胜感激

非常感谢

SELECT ROW_NUMBER() OVER(ORDER BY ' + @SortField + '   ' + @SortOrder + ') AS RowNum,
                                  ^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^
                                    string #1              string #2

                                                      ^---no operator

除非您的代码示例中没有显示外部字符串,否则无法构建这样的ORDERBY子句。两个不同的带引号的字符串之间有一个空格。

不能用变量指定字段或排序方向。要做到这一点,整个SQL语句必须是动态字符串

所以

一切都很好

exec('SELECT ROW_NUMBER() OVER(' + 
    'ORDER BY ' + @SortField + ' ' + @SortOrder + ') AS RowNum ...')
但是


SQL中的查询编译器无法处理此问题。

看起来您正试图通过
行数()排序函数动态更改字段的顺序。你不能用你正在尝试的方式去做

您需要使用动态SQL来完成您正在尝试的任务。您应该阅读本书,以便更好地理解机制以及如何保护自己免受SQL注入的影响

如果出于某种原因您不想使用动态SQL,那么您可以生成一个巨大的case语句。例如,下面的示例取自gbn对的回答


如果这样做,您应该注意性能问题,因为索引可能不用于排序。

有什么办法可以解决这个问题吗?我真的需要这里的帮助。@neojakey-前两个选项中的任何一个都可以。基本上,
order by
中要么有静态字段,要么整个语句必须是动态字符串。这是因为您选择按
排序可以完全改变查询计划及其优化方式,因此SQL在缓存它时没有任何价值。@neojakey-有一种方法可以绕过这一点,但这很糟糕。存储过程中只能有
MemberMail
Member
表中的排序字段,因此可以对每个可排序字段重复整个语句。这将是非常难看的代码,但会给出SQL查询计划,它可以缓存。我为ASC和DESC重复了整个语句2次。非常感谢您的帮助。。!很好的解决方案-您可以使用子查询进一步简化它,其中
case
开关是一个选择。然后,您就有了跨越该行的
row\u number()
函数。
exec('SELECT ROW_NUMBER() OVER(' + 
    'ORDER BY ' + @SortField + ' ' + @SortOrder + ') AS RowNum ...')
SELECT ROW_NUMBER() OVER(
    ORDER BY ' + @SortField + ' ' + @SortOrder + ') AS RowNum
SELECT
     Columns you actually want
FROM
    (
    SELECT
         Columns you actually want,
         ROW_NUMBER() OVER (ORDER BY AddedDate) AS AddedDateSort,
         ROW_NUMBER() OVER (ORDER BY Visible) AS VisibleSort,
         ROW_NUMBER() OVER (ORDER BY AddedBy) AS AddedBySort,
         ROW_NUMBER() OVER (ORDER BY Title) AS TitleSort
    FROM
         myTable
    WHERE
         MyFilters...
    ) foo
ORDER BY
     CASE @OrderByColumn
        WHEN 'AddedDate' THEN AddedDateSort
        WHEN 'Visible' THEN VisibleSort    
        WHEN 'AddedBy' THEN AddedBySort
        WHEN 'Title' THEN TitleSort
     END * @multiplier;