在存储过程中多次使用SQL WITH语句的结果

时间:2013-01-21 01:53:16

标签: sql sql-server-2008 stored-procedures with-statement

我有下面的SQL存储过程:

ALTER PROCEDURE [dbo].[sp_getpaginatedusersbyglobalfilter] 
    @globalFilter varchar(max)
    , @pageSize int
    , @page int
    , @totalRecords int output
    , @totalFilteredRecords int output
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    ;WITH PaginatedUsers AS(
        SELECT     ROW_NUMBER() OVER(ORDER BY u.LastName) ID
                   , u.Username
                   , u.FirstName
                   , u.OtherNames
                   , u.LastName
                   , e.Nombre
                   , r.RoleName
                   , u.PhoneNumber
        FROM       webpages_Users u
        INNER JOIN Establecimiento e
        ON         u.FacilityId = e.IDReporte
        AND        e.EstadoRegistro = 1
        INNER JOIN webpages_UsersInRoles ur
        ON         u.UserId = ur.UserId
        INNER JOIN webpages_Roles r
        ON         ur.RoleId = r.RoleId
        WHERE      u.Username LIKE '%' + @globalFilter + '%'
        OR         u.FirstName LIKE '%' + @globalFilter + '%' 
        OR         u.OtherNames LIKE '%' + @globalFilter + '%'
        OR         u.LastName LIKE '%' + @globalFilter + '%'
        OR         e.Nombre LIKE '%' + @globalFilter + '%'
        OR         r.RoleName LIKE '%' + @globalFilter + '%'
        OR         u.PhoneNumber LIKE '%' + @globalFilter + '%'
    )

    SELECT  pu.ID, pu.Username
            , pu.FirstName
            , pu.OtherNames
            , pu.LastName
            , pu.Nombre AS FacilityName
            , pu.RoleName
            , pu.PhoneNumber
    FROM    PaginatedUsers pu
    WHERE   pu.ID BETWEEN ((@page - 1) * @pageSize + 1)
    AND     @page * @pageSize

    SELECT @totalFilteredRecords = COUNT(pu.ID)
    FROM    PaginatedUsers pu

    SELECT @totalRecords = COUNT(u.UserId)
    FROM   webpages_Users u
END

我遇到的问题是:

    SELECT @totalFilteredRecords = COUNT(pu.ID)
    FROM    PaginatedUsers pu

我得到的错误是“无效的对象名称'PaginatedUsers'”。根据我的研究,我不能在查询中多次使用PaginatedUsers(由WITH产生)对象。那么,我该怎么做才能返回输出变量@totalFilteredRecords中的记录总数?我一直在考虑将结果插入到临时表中,然后从中获取计数以及最终结果集,但我不喜欢这个想法。我该怎么办?

感谢。

2 个答案:

答案 0 :(得分:0)

您只能在与With子句相同的语句中使用With子句的输出。第一个Select子句是以With子句开头的第一个SQL语句的一部分。通过使用第二个Select,它位于单独的SQL语句中。如果将两个Selects连接到一个语句中,那么它将起作用。

答案 1 :(得分:0)

您的研究是正确的,您不能多次使用CTE。

- 编辑

AS OP指出,为变量赋值的SELECT语句不能与数据检索操作相结合。

所以我没有任何其他建议而不是使用临时表 - 这是一个未经测试的例子:

SELECT     ROW_NUMBER() OVER(ORDER BY u.LastName) ID
               , u.Username
               , u.FirstName
               , u.OtherNames
               , u.LastName
               , e.Nombre
               , r.RoleName
               , u.PhoneNumber
       INTO #PaginatedUsers
FROM       webpages_Users u
    INNER JOIN Establecimiento e
    ON         u.FacilityId = e.IDReporte
    AND        e.EstadoRegistro = 1
    INNER JOIN webpages_UsersInRoles ur
    ON         u.UserId = ur.UserId
    INNER JOIN webpages_Roles r
    ON         ur.RoleId = r.RoleId
WHERE      u.Username LIKE '%' + @globalFilter + '%'
    OR         u.FirstName LIKE '%' + @globalFilter + '%' 
    OR         u.OtherNames LIKE '%' + @globalFilter + '%'
    OR         u.LastName LIKE '%' + @globalFilter + '%'
    OR         e.Nombre LIKE '%' + @globalFilter + '%'
    OR         r.RoleName LIKE '%' + @globalFilter + '%'
    OR         u.PhoneNumber LIKE '%' + @globalFilter + '%'


SELECT  pu.ID, pu.Username
        , pu.FirstName
        , pu.OtherNames
        , pu.LastName
        , pu.Nombre AS FacilityName
        , pu.RoleName
        , pu.PhoneNumber
FROM    #PaginatedUsers pu
WHERE   pu.ID BETWEEN ((@page - 1) * @pageSize + 1)
AND     @page * @pageSize

SELECT @totalFilteredRecords = COUNT(pu.ID)
FROM    #PaginatedUsers pu

SELECT @totalRecords = COUNT(u.UserId)
FROM   webpages_Users u

DROP TABLE #PaginatedUsers

这是一篇很好的answer我读到的有关CTE与临时表的内容。

相关问题