2010-08-07 98 views
0

我已經創建了以下在我的SQL Server存儲過程一般分頁2005數據庫:需要幫助一般的SQL存儲過程分頁

USE [training] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE PROCEDURE [dbo].[usp_Pagination1] 
    -- Add the parameters for the stored procedure here 
    @SqlColumns VARCHAR(MAX), 
    @SqlFriendlyColumns VARCHAR(MAX), 
    @SqlTableClause VARCHAR(MAX), 
    @StartRow INT, 
    @EndRow INT, 
    @SqlWhere VARCHAR(MAX), 
    @SqlOuterWhere VARCHAR(MAX), 
    @SqlRowNumOrderBy VARCHAR(MAX), 
    @SqlOuterOrderBy VARCHAR(MAX) 
AS 
DECLARE @rsSQL NVARCHAR(MAX) 
DECLARE @rcSQL NVARCHAR(MAX) 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 
/* 
sample dynamically created SQL: 
    WITH PersonContact AS 
    ( 
     SELECT PC.FirstName, PC.LastName, PC.EmailAddress, 
     ROW_NUMBER() OVER(ORDER BY PC.ContactID) AS RowNumber 
     FROM Person.Contact PC 
    ) 
    SELECT FirstName, LastName, EmailAddress 
    FROM PersonContact 
    WHERE RowNumber > @StartRow AND RowNumber < @EndRow 
    ORDER BY LastName DESC, EmailAddress 
*/ 
    -- build pagination SQL, using StartRow and EndRow to determine 
    -- which results to output 
    SET @rsSQL = N' WITH tempTable AS (' + 
     N' SELECT ' + 
      @SqlColumns + 
     N' , ROW_NUMBER() OVER(ORDER BY ' + 
      @SqlRowNumOrderBy + 
     N') AS RowNumber ' + 
     N' FROM ' + 
      @SqlTableClause 
    IF @SqlWhere + '' <> '' 
     BEGIN 
      SET @rsSQL = @rsSQL +     
       N' WHERE ' + 
        @SqlWhere 
     END 
    SET @rsSQL = @rsSQL + 
     N') SELECT ' + 
      @SqlFriendlyColumns + 
     N' FROM tempTable ' + 
     N' WHERE RowNumber >= ' + 
      CAST(@StartRow AS NVARCHAR(32)) + 
     N' AND RowNumber <= ' + 
      CAST(@EndRow AS NVARCHAR(32)) + 
     N' ORDER BY ' + 
      @SqlOuterOrderBy 

    -- uncomment PRINT to debug 
    PRINT @rsSQL 
    EXEC sp_executesql @rsSQL 
    -- build second recordset simple for the count 
    SET @rcSQL = 
      N'SELECT COUNT(*) AS CountAll FROM ' + 
       @SqlTableClause 
    IF @SqlOuterWhere + '' <> '' 
     BEGIN 
      SET @rcSQL = @rcSQL +     
       N' WHERE ' + 
         @SqlOuterWhere 
     END 

    EXEC sp_executesql @rcSQL  
    SET NOCOUNT OFF; 
END 

執行的過程與我的參數:

USE [training] 
GO 

EXEC [dbo].[usp_Pagination1] 
     @SqlColumns = N'tab1.categoryId,tab1.categoryName,tab1.description,tab1.parentCategory,tab2.categoryName AS parentCategoryName', 
     @SqlFriendlyColumns = N'categoryId,categoryName,description,parentCategory,parentCategoryName', 
     @SqlTableClause = N'vpCategory tab1 LEFT JOIN vpCategory tab2 ON tab1.parentCategory = tab2.categoryId', 
     @StartRow = 1, 
     @EndRow = 1, 
     @SqlWhere = N'tab1.categoryId = 1', 
     @SqlOuterWhere = N'categoryId = 1', 
     @SqlRowNumOrderBy = N'tab1.categoryId', 
     @SqlOuterOrderBy = N'categoryId' 

GO 

當我執行它爲我的表vpCategory,我得到消息: 消息209,級別16,狀態1,行1 模糊列名'categoryId'。

但在結果選項卡它給我正確的輸出。

還可以留言選項卡提供了以下查詢我來說,這是由程序內置:

WITH tempTable AS ( SELECT tab1.categoryId,tab1.categoryName,tab1.description,tab1.parentCategory,tab2.categoryName AS parentCategoryName , ROW_NUMBER() OVER(ORDER BY tab1.categoryId) AS RowNumber FROM vpCategory tab1 LEFT JOIN vpCategory tab2 ON tab1.parentCategory = tab2.categoryId WHERE tab1.categoryId = 1) SELECT categoryId,categoryName,description,parentCategory,parentCategoryName FROM tempTable WHERE RowNumber >= 1 AND RowNumber <= 1 ORDER BY categoryId 

當我執行新的窗口上面的查詢,它給了我沒有錯誤!

任何人都可以幫助我瞭解存儲過程出了什麼問題嗎?

+3

如果您不介意我說,在程序中執行所有動態SQL,那麼存儲過程根本沒有多大價值。在調用此過程之前,您的客戶將很難驗證和清理輸入以防止SQL注入。 – kbrimington 2010-08-07 06:27:09

+1

準確確定哪些表或查詢需要分頁然後構建存儲過程以迎合這些顯式方案是否更有意義? – RobS 2010-08-07 06:32:30

+0

我同意@kbrimington,我將用編程語言的動態查詢來替代存儲過程調用。 – Vikas 2010-08-07 09:21:59

回答

0

明白了!

其實我們點需要外在哪裏鱈魚。

是:

ALTER PROCEDURE [dbo].[usp_Pagination] 
    -- Add the parameters for the stored procedure here 
    @SqlColumns VARCHAR(MAX), 
    @SqlFriendlyColumns VARCHAR(MAX), 
    @SqlTableClause VARCHAR(MAX), 
    @StartRow INT, 
    @EndRow INT, 
    @SqlWhere VARCHAR(MAX), 
    @SqlRowNumOrderBy VARCHAR(MAX), 
    @SqlOuterOrderBy VARCHAR(MAX) 
AS 
DECLARE @rsSQL NVARCHAR(MAX) 
DECLARE @rcSQL NVARCHAR(MAX) 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 
/* 
sample dynamically created SQL: 
    WITH PersonContact AS 
    ( 
     SELECT PC.FirstName, PC.LastName, PC.EmailAddress, 
     ROW_NUMBER() OVER(ORDER BY PC.ContactID) AS RowNumber 
     FROM Person.Contact PC 
    ) 
    SELECT FirstName, LastName, EmailAddress 
    FROM PersonContact 
    WHERE RowNumber > @StartRow AND RowNumber < @EndRow 
    ORDER BY LastName DESC, EmailAddress 
*/ 
    -- build pagination SQL, using StartRow and EndRow to determine 
    -- which results to output 
    SET @rsSQL = N' WITH tempTable AS (' + 
     N' SELECT ' + 
      @SqlColumns + 
     N' , ROW_NUMBER() OVER(ORDER BY ' + 
      @SqlRowNumOrderBy + 
     N') AS RowNumber ' + 
     N' FROM ' + 
      @SqlTableClause 
    IF @SqlWhere + '' <> '' 
     BEGIN 
      SET @rsSQL = @rsSQL +     
       N' WHERE ' + 
        @SqlWhere 
     END 
    SET @rsSQL = @rsSQL + 
     N') SELECT ' + 
      @SqlFriendlyColumns + 
     N' FROM tempTable ' + 
     N' WHERE RowNumber >= ' + 
      CAST(@StartRow AS NVARCHAR(32)) + 
     N' AND RowNumber <= ' + 
      CAST(@EndRow AS NVARCHAR(32)) + 
     N' ORDER BY ' + 
      @SqlOuterOrderBy 

    -- uncomment PRINT to debug 
    PRINT @rsSQL 
    EXEC sp_executesql @rsSQL 
    -- build second recordset simple for the count 
    SET @rcSQL = 
      N'SELECT COUNT(*) AS CountAll FROM ' + 
       @SqlTableClause 
    IF @SqlWhere + '' <> '' 
     BEGIN 
      SET @rcSQL = @rcSQL +     
       N' WHERE ' + 
        @SqlWhere 
     END 

    EXEC sp_executesql @rcSQL  
    SET NOCOUNT OFF; 
END 
0

看起來像你的第二個sp_executesql的可以產生這個錯誤-the @SqlOuterWhere應該CategoryID列使用別名。