SQL Server中带变量的分页排序
此SQL语句在SQL Server中的标记顺序为'+@SortField+'+@SortOrder+'部分。。有什么好主意吗?我怎么修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
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;