繁体   English   中英

分页脚本中的存储过程和输出参数(SQL Server 2008)

[英]Stored Procedure and output parameter from paging script (SQL Server 2008)

我有下面的存储过程,并希望只有一个SQL语句。 目前您可以看到有两个语句,一个用于实际的分页,另一个用于需要返回到我的应用程序进行分页的总记录数。

但是,由于我从第一个查询获取总行数,因此下面的效率很低:

COUNT(*) OVER(PARTITION BY 1) as TotalRows

如何将TotalRows设置为输出参数?

ALTER PROCEDURE [dbo].[Nop_LoadAllOptimized]
(
    @PageSize int = null,
    @PageNumber int = null,
    @WarehouseCombinationID int = null,
    @CategoryId int = null,
    @OrderBy int = null,
    @TotalRecords int = null OUTPUT
)
AS
BEGIN

WITH Paging AS (
    SELECT rn = (ROW_NUMBER() OVER (
    ORDER BY 
        CASE WHEN @OrderBy = 0 AND @CategoryID IS NOT NULL AND @CategoryID > 0
        THEN pcm.DisplayOrder END ASC,
        CASE WHEN @OrderBy = 0
        THEN p.[Name] END ASC,
        CASE WHEN @OrderBy = 5
        THEN p.[Name] END ASC,
        CASE WHEN @OrderBy = 10
        THEN wpv.Price END ASC,
        CASE WHEN @OrderBy = 15
        THEN wpv.Price END DESC,
        CASE WHEN @OrderBy = 20
        THEN wpv.Price END DESC,
        CASE WHEN @OrderBy = 25
        THEN wpv.UnitPrice END ASC  
    )),COUNT(*) OVER(PARTITION BY 1) as TotalRows, p.*, pcm.DisplayOrder, wpv.Price, wpv.UnitPrice FROM Nop_Product p
    INNER JOIN Nop_Product_Category_Mapping pcm ON p.ProductID=pcm.ProductID
    INNER JOIN Nop_ProductVariant pv ON p.ProductID = pv.ProductID
    INNER JOIN Nop_ProductVariant_Warehouse_Mapping wpv ON pv.ProductVariantID = wpv.ProductVariantID
    WHERE pcm.CategoryID = @CategoryId
    AND (wpv.Published = 1 AND pv.Published = 1 AND p.Published = 1 AND p.Deleted = 0 AND pv.Deleted = 0 and wpv.Deleted = 0)
    AND wpv.WarehouseID IN (select WarehouseID from Nop_WarehouseCombination where UserWarehouseCombinationID = @WarehouseCombinationID)    
)
SELECT TOP (@PageSize) * FROM Paging PG
WHERE PG.rn > (@PageNumber * @PageSize) - @PageSize 

SELECT @TotalRecords = COUNT(p.ProductId) FROM Nop_Product p
INNER JOIN Nop_Product_Category_Mapping pcm ON p.ProductID=pcm.ProductID
INNER JOIN Nop_ProductVariant pv ON p.ProductID = pv.ProductID
INNER JOIN Nop_ProductVariant_Warehouse_Mapping wpv ON pv.ProductVariantID = wpv.ProductVariantID
WHERE pcm.CategoryID = @CategoryId
AND (wpv.Published = 1 AND pv.Published = 1 AND p.Published = 1 AND p.Deleted = 0 AND pv.Deleted = 0 and wpv.Deleted = 0)
AND wpv.WarehouseID IN (select WarehouseID from Nop_WarehouseCombination where UserWarehouseCombinationID = @WarehouseCombinationID)


END

我想我在这里理解你的问题。 您是否认为计数可以在CTE之前完成,然后作为变量传递给CTE作为值。

即,预先设置@TotalRecords的值,传入,然后CTE将使用此计数而不是第二次执行计数?

这是否有意义,或者我在这里错过了你的观点。

没问题的朋友,我极有可能在这里错过了一招。 但是,如果没有架构和数据,那么测试我的建议就很棘手。 在没有人给出更好的答案的情况下,我将这个测试脚本与数据放在一起来演示我正在谈论的内容。 如果这不是你想要的那么没问题。 如果它再次明显地忽略了这一点,那么我会把它放在下巴上。

Declare @pagesize as int 
Declare @PageNumber as int 
Declare @TotalRowsOutputParm as int

SET @pagesize = 3
SET @PageNumber = 2;

--create some test data
DECLARE @SomeData  table
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [SomeValue] [nchar](10) NULL
) 

INSERT INTO @SomeData VALUES    ('TEST1')
INSERT INTO @SomeData VALUES    ('TEST2')
INSERT INTO @SomeData VALUES    ('TEST3')
INSERT INTO @SomeData VALUES    ('TEST4')
INSERT INTO @SomeData VALUES    ('TEST5')
INSERT INTO @SomeData VALUES    ('TEST6')
INSERT INTO @SomeData VALUES    ('TEST7')
INSERT INTO @SomeData VALUES    ('TEST8')
INSERT INTO @SomeData VALUES    ('TEST9')
INSERT INTO @SomeData VALUES    ('TEST10');

--Get total count of all rows
Set @TotalRowsOutputParm = (SELECT COUNT(SomeValue) FROM @SomeData p) ;

WITH Paging AS 
(    
   SELECT rn = (ROW_NUMBER() OVER (ORDER BY  SomeValue ASC)),
   @TotalRowsOutputParm as TotalRows, p.* 
   FROM [SomeData] p    
)

SELECT TOP (@PageSize) * FROM Paging PG
WHERE PG.rn > (@PageNumber * @PageSize) - @PageSize 

PRINT @TotalRowsOutputParm

如果你想将它分配给一个变量,我认为如果不运行两次查询就不能这样做

但是,您不能只添加另一列并执行此类操作吗?

;WITH Paging AS (select *,ROW_NUMBER() OVER(ORDER BY name) AS rn FROM sysobjects)

SELECT (SELECT MAX(rn) FROM Paging) AS TotalRecords,* FROM Paging
WHERE rn < 10

或者在你的情况下

SELECT TOP (@PageSize) *,(SELECT MAX(PG.rn) FROM Paging) AS TotalRecords 
FROM Paging PG
WHERE PG.rn > (@PageNumber * @PageSize) - @PageSize 

然后从前端抓住那一列

最后我决定使用两个不同的SQL语句,一个用于计数,一个用于select。

“COUNT(*)OVER(PARTITION BY 1)作为TotalRows”实际上非常昂贵,而且使用两个不同的语句更快。

谢谢所有帮助过这个问题的人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM