【问题标题】:How to count results of stored procedure and show only 100 rows如何计算存储过程的结果并仅显示 100 行
【发布时间】:2017-05-10 05:58:26
【问题描述】:

我编写了一个存储过程来搜索我的数据库中的用户。但有时它返回的用户太多,而且耗时太长。

所以如果结果集有超过 500 行,我决定只返回前 500 行。但我不知道如何从存储过程中获取计数。

请帮助我。

我的原始存储过程如下。谢谢

ALTER PROCEDURE [dbo].[up_Select_SearchUser]
    @companyCode    varchar(50)
,   @keyword        nvarchar(20)
,   @isRelative     bit
,   @langCode       varchar(10)
AS
BEGIN
    SET NOCOUNT ON;

    SELECT     
        LOWER(M.UserID) AS EmpID,
        LOWER(M.EmpID) AS REmpID,
        dbo.uf_CompanyPhone(M.CompanyPhone, M.ExtensionNumber) AS ExtensionNumber,  
        M.CellPhone,
        dbo.uf_TeamManagerYN(M.UserID) AS TeamChiefYN, 
        ISNULL(M.DisplayName, '') AS DisplayName, 
        ISNULL(M.DisplayName_Eng, '') AS DisplayName_Eng,
        M.EMail, 
        M.MainDeptCode AS DeptCode,
        ISNULL(DT.DisplayName, '') AS DeptName,
        ISNULL(CL.CompanyCode, '') AS CompanyCode,
        ISNULL(CL.CompanyName, '') AS CompanyName,
        ISNULL(R.RankCode, '') AS RankCode,
        ISNULL(R.RankName, '') AS RankName, 
        ISNULL(J.JobCode, '') AS JobCode,
        ISNULL(J.JobName, '') AS JobName,
        ISNULL(D.DutyCode, '') AS DutyCode,
        ISNULL(D.DutyName, '') AS DutyName,
        ISNULL(M.FaxNumber, '') AS FaxNumber,
        ISNULL(M.ADDisplayName, '') AS ADDisplayName,
        '' AS Address,
        ISNULL(M.CompanyPhone, '') AS CompanyPhone, 
        ISNULL(R.SortOrder, '') AS RankOrder
    FROM     
        dbo.tb_User M WITH (NOLOCK) 
    INNER JOIN 
        dbo.tb_Dept DT WITH (NOLOCK) ON M.MainDeptCode = DT.DeptCode 
    INNER JOIN 
        dbo.tb_Rank R WITH (NOLOCK) ON M.RankCode = R.RankCode
                                    AND M.GroupCode = R.GroupCode
                                    AND M.DetailCode = R.DetailCode
                                    AND M.CompanyCode = R.CompanyCode
    INNER JOIN 
        dbo.tb_Company CL WITH (NOLOCK) ON M.CompanyCode = CL.CompanyCode
    LEFT OUTER JOIN 
        dbo.tb_Duty D WITH (NOLOCK) ON M.DutyCode = D.DutyCode 
                                    AND M.GroupCode = D.GroupCode
                                    AND M.DetailCode = D.DetailCode
                                    AND M.CompanyCode = D.CompanyCode
    LEFT OUTER JOIN 
        dbo.tb_Job J WITH (NOLOCK) ON M.JobCode = J.JobCode 
    WHERE    
        (M.DisplayName LIKE '%' + @keyword + '%' 
         OR M.UserID LIKE '%' + @keyword + '%') 
        AND M.DisplayYN = 'Y' 
        AND M.CompanyCode LIKE @companyCode
    ORDER BY 
        RankOrder, JobCode, DisplayName
END

【问题讨论】:

  • 肯定有成千上万个这样的例子......请尝试搜索。另外:模式、索引、S-argable
  • 使用SELECT TOP 500
  • 如果您正在挖掘重复记录,您应该查看您的联接。
  • 为什么不尝试使用 OFFSET / FETCH 进行分页,我们可以每页显示 100 行或更多行
  • 是的,深入你的加入,找出为什么你会得到很多记录。分页,只有你正在寻找的分页。

标签: sql sql-server stored-procedures count


【解决方案1】:

TOP 500 添加到select 查询。这将确保结果计数不会超过 500。如果它小于 500,它将获取记录数。如果它大于 500,它将过滤前 500 条记录。

ALTER PROCEDURE [dbo].[up_Select_SearchUser]
    @companyCode    varchar(50)
,   @keyword        nvarchar(20)
,   @isRelative     bit
,   @langCode       varchar(10)
AS
BEGIN
    SET NOCOUNT ON;

SELECT  TOP 500   LOWER(M.UserID)                                            AS EmpID 
         , LOWER(M.EmpID)                                             AS REmpID 
         , dbo.uf_CompanyPhone(M.CompanyPhone, M.ExtensionNumber)     AS ExtensionNumber 
         , M.CellPhone 
         , dbo.uf_TeamManagerYN(M.UserID)                             AS TeamChiefYN 
         , ISNULL(M.DisplayName,'')                                   AS DisplayName 
         , ISNULL(M.DisplayName_Eng,'')                               AS DisplayName_Eng 
         , M.EMail 
         , M.MainDeptCode                                             AS DeptCode 
         , ISNULL(DT.DisplayName,'')                                  AS DeptName 
         , ISNULL(CL.CompanyCode,'')                                  AS CompanyCode 
         , ISNULL(CL.CompanyName,'')                                  AS CompanyName 
         , ISNULL(R.RankCode,'')                                      AS RankCode 
         , ISNULL(R.RankName,'')                                      AS RankName 
         , ISNULL(J.JobCode,'')                                       AS JobCode 
         , ISNULL(J.JobName,'')                                       AS JobName 
         , ISNULL(D.DutyCode,'')                                      AS DutyCode 
         , ISNULL(D.DutyName,'')                                      AS DutyName 
         , ISNULL(M.FaxNumber,'')                                     AS FaxNumber 
         , ISNULL(M.ADDisplayName,'')                                 AS ADDisplayName 
         , ''                                                         AS Address
         , ISNULL(M.CompanyPhone, '')                                 AS CompanyPhone
         , ISNULL(R.SortOrder,'')                                     AS RankOrder
FROM     dbo.tb_User M WITH (NOLOCK) 
         INNER JOIN dbo.tb_Dept DT WITH (NOLOCK) 
            ON M.MainDeptCode = DT.DeptCode 
         INNER JOIN dbo.tb_Rank R WITH (NOLOCK) 
            ON M.RankCode = R.RankCode
            AND M.GroupCode = R.GroupCode
            AND M.DetailCode = R.DetailCode
            AND M.CompanyCode = R.CompanyCode
         INNER JOIN dbo.tb_Company CL WITH (NOLOCK) 
            ON M.CompanyCode = CL.CompanyCode             
         LEFT OUTER JOIN dbo.tb_Duty D WITH (NOLOCK) 
            ON M.DutyCode = D.DutyCode 
            AND M.GroupCode = D.GroupCode
            AND M.DetailCode = D.DetailCode
            AND M.CompanyCode = D.CompanyCode
         LEFT OUTER JOIN dbo.tb_Job J WITH (NOLOCK) 
            ON M.JobCode = J.JobCode 
WHERE    (M.DisplayName LIKE '%' + @keyword + '%' 
           OR M.UserID LIKE '%' + @keyword + '%') 
         AND M.DisplayYN = 'Y' 
         AND M.CompanyCode LIKE @companyCode
ORDER BY RankOrder , JobCode, DisplayName

【讨论】:

  • 您确定执行时间吗?
【解决方案2】:

使用此语句代替 SELECT TOP:

SELECT * FROM Products
WHERE id BETWEEN 10 AND 20;

为了更好的控制

为了更好的例子wiev: Equivalent of LIMIT and OFFSET for SQL Server?

【讨论】:

  • 这只是一个示例,但可以对其进行修改以适合您的查询
  • 如果他们的id从1000开始呢?
  • @SankarRaj 这适用于未删除 ID 的数据库,您可以使用 COUNT 获取最大值并使用它
【解决方案3】:

我从你的问题中了解到,你只想选择 500 或 100 条记录,这取决于你想选择多少条记录,你可以使用

select top 500 [lisofyourcolums] from your table;

如果您想进行分页,您可以简单地在您的存储过程中进行更改,如下所示

ALTER PROCEDURE [dbo].[up_Select_SearchUser]
    @companyCode    varchar(50)
,   @keyword        nvarchar(20)
,   @isRelative     bit
,   @langCode       varchar(10)
,   @startRowIndex int=1
,   @maximumRows int=500
AS
BEGIN
SET NOCOUNT ON;
      DECLARE  @startRow int,@totalRows int
    SET @startRowIndex =  (@startRowIndex - 1)  * @maximumRows
    Print @startRowIndex

    IF @startRowIndex = 0 
     SET @startRowIndex = 1
    Else
     SET @startRowIndex = @startRowIndex+1
    Print @startRowIndex
    SET ROWCOUNT @startRowIndex  


    select [yourcolumnList] from yourtable 

    SET ROWCOUNT @maximumRows 


SELECT  

END

希望对你有帮助……

【讨论】:

    【解决方案4】:
    Select @Count = COUNT() 
    From Table 
    Where <Your Condition>
    

    然后使用IF声明:

    if @Count > 500 then 
        SELECT TOP 500 
            LOWER(M.UserID) = AS EmpID 
    

    【讨论】:

      【解决方案5】:

      试试这个

      ALTER PROCEDURE [dbo].[up_Select_SearchUser]
              @companyCode    varchar(50)
          ,   @keyword        nvarchar(20)
          ,   @isRelative     bit
          ,   @langCode       varchar(10)
          ,   @PageNumber INT = 1--Give Page number you required 
          ,   @PageSize   INT = 100 --Give number of rows you required per Page
          AS
          BEGIN
              SET NOCOUNT ON;
      
      
          SELECT     LOWER(M.UserID)                                            AS EmpID 
                   , LOWER(M.EmpID)                                             AS REmpID 
                   , dbo.uf_CompanyPhone(M.CompanyPhone, M.ExtensionNumber)     AS ExtensionNumber 
                   , M.CellPhone 
                   , dbo.uf_TeamManagerYN(M.UserID)                             AS TeamChiefYN 
                   , ISNULL(M.DisplayName,'')                                   AS DisplayName 
                   , ISNULL(M.DisplayName_Eng,'')                               AS DisplayName_Eng 
                   , M.EMail 
                   , M.MainDeptCode                                             AS DeptCode 
                   , ISNULL(DT.DisplayName,'')                                  AS DeptName 
                   , ISNULL(CL.CompanyCode,'')                                  AS CompanyCode 
                   , ISNULL(CL.CompanyName,'')                                  AS CompanyName 
                   , ISNULL(R.RankCode,'')                                      AS RankCode 
                   , ISNULL(R.RankName,'')                                      AS RankName 
                   , ISNULL(J.JobCode,'')                                       AS JobCode 
                   , ISNULL(J.JobName,'')                                       AS JobName 
                   , ISNULL(D.DutyCode,'')                                      AS DutyCode 
                   , ISNULL(D.DutyName,'')                                      AS DutyName 
                   , ISNULL(M.FaxNumber,'')                                     AS FaxNumber 
                   , ISNULL(M.ADDisplayName,'')                                 AS ADDisplayName 
                   , ''                                                         AS Address
                   , ISNULL(M.CompanyPhone, '')                                 AS CompanyPhone
                   , ISNULL(R.SortOrder,'')                                     AS RankOrder
          FROM     dbo.tb_User M WITH (NOLOCK) 
                   INNER JOIN dbo.tb_Dept DT WITH (NOLOCK) 
                      ON M.MainDeptCode = DT.DeptCode 
                   INNER JOIN dbo.tb_Rank R WITH (NOLOCK) 
                      ON M.RankCode = R.RankCode
                      AND M.GroupCode = R.GroupCode
                      AND M.DetailCode = R.DetailCode
                      AND M.CompanyCode = R.CompanyCode
                   INNER JOIN dbo.tb_Company CL WITH (NOLOCK) 
                      ON M.CompanyCode = CL.CompanyCode             
                   LEFT OUTER JOIN dbo.tb_Duty D WITH (NOLOCK) 
                      ON M.DutyCode = D.DutyCode 
                      AND M.GroupCode = D.GroupCode
                      AND M.DetailCode = D.DetailCode
                      AND M.CompanyCode = D.CompanyCode
                   LEFT OUTER JOIN dbo.tb_Job J WITH (NOLOCK) 
                      ON M.JobCode = J.JobCode 
          WHERE    (M.DisplayName LIKE '%' + @keyword + '%' 
                     OR M.UserID LIKE '%' + @keyword + '%') 
                   AND M.DisplayYN = 'Y' 
                   AND M.CompanyCode LIKE @companyCode
          ORDER BY RankOrder , JobCode, DisplayName
      
              OFFSET @PageSize * (@PageNumber - 1) ROWS
              FETCH NEXT @PageSize ROWS ONLY 
      
      
          END
      

      【讨论】:

        【解决方案6】:

        声明一个变量来获取用户的输入以显示他想要返回多少条记录

        ALTER PROCEDURE [dbo].[up_Select_SearchUser]
            @companyCode    varchar(50)
        ,   @keyword        nvarchar(20)
        ,   @isRelative     bit
        ,   @langCode       varchar(10)
        ,   @NumberOfRows INT
        AS
        BEGIN
            SET NOCOUNT ON;
        
        SELECT TOP @NumberOfRows 
            LOWER(M.UserID) AS EmpID,
            LOWER(M.EmpID) AS REmpID,
            dbo.uf_CompanyPhone(M.CompanyPhone, M.ExtensionNumber) AS ExtensionNumber,  
            M.CellPhone,
            dbo.uf_TeamManagerYN(M.UserID) AS TeamChiefYN, 
            ISNULL(M.DisplayName, '') AS DisplayName, 
            ISNULL(M.DisplayName_Eng, '') AS DisplayName_Eng,
            M.EMail, 
            M.MainDeptCode AS DeptCode,
            ISNULL(DT.DisplayName, '') AS DeptName,
            ISNULL(CL.CompanyCode, '') AS CompanyCode,
            ISNULL(CL.CompanyName, '') AS CompanyName,
            ISNULL(R.RankCode, '') AS RankCode,
            ISNULL(R.RankName, '') AS RankName, 
            ISNULL(J.JobCode, '') AS JobCode,
            ISNULL(J.JobName, '') AS JobName,
            ISNULL(D.DutyCode, '') AS DutyCode,
            ISNULL(D.DutyName, '') AS DutyName,
            ISNULL(M.FaxNumber, '') AS FaxNumber,
            ISNULL(M.ADDisplayName, '') AS ADDisplayName,
            '' AS Address,
            ISNULL(M.CompanyPhone, '') AS CompanyPhone, 
            ISNULL(R.SortOrder, '') AS RankOrder
        FROM     
            dbo.tb_User M WITH (NOLOCK) 
        INNER JOIN 
            dbo.tb_Dept DT WITH (NOLOCK) ON M.MainDeptCode = DT.DeptCode 
        INNER JOIN 
            dbo.tb_Rank R WITH (NOLOCK) ON M.RankCode = R.RankCode
                                        AND M.GroupCode = R.GroupCode
                                        AND M.DetailCode = R.DetailCode
                                        AND M.CompanyCode = R.CompanyCode
        INNER JOIN 
            dbo.tb_Company CL WITH (NOLOCK) ON M.CompanyCode = CL.CompanyCode
        LEFT OUTER JOIN 
            dbo.tb_Duty D WITH (NOLOCK) ON M.DutyCode = D.DutyCode 
                                        AND M.GroupCode = D.GroupCode
                                        AND M.DetailCode = D.DetailCode
                                        AND M.CompanyCode = D.CompanyCode
        LEFT OUTER JOIN 
            dbo.tb_Job J WITH (NOLOCK) ON M.JobCode = J.JobCode 
        WHERE    
            (M.DisplayName LIKE '%' + @keyword + '%' 
             OR M.UserID LIKE '%' + @keyword + '%') 
            AND M.DisplayYN = 'Y' 
            AND M.CompanyCode LIKE @companyCode
        ORDER BY 
            RankOrder, JobCode, DisplayName
        END
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-12-21
          • 1970-01-01
          • 2018-03-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-22
          相关资源
          最近更新 更多