2010-07-12 207 views
0

我有一個存儲過程,獲取項目列表,排序和應用分頁。
但是我也需要添加過濾。因此,我想要做的是通過在過濾器 像「27 =‘有些公司’; 32 ='奧克蘭」的字符串,並將其分割成一個臨時表(見下文分裂代碼)如何將動態過濾器傳遞到存儲過程與分頁

建議拆分代碼

CREATE TABLE #Filters 
    (  
     ModelEntityId int not null, 
     ValueText nvarchar(max) 
    ) 

    WHILE (@pos <> 0) 
    BEGIN 
     SET @NextFilter = substring(@Filters,1,@Pos - 1) 
     SET @SubPos = charindex('=',@NextFilter) 

     insert into #Filters (ModelEntityId, ValueText) 
       Values (substring(@NextFilter, 1, @SubPos-1), 
         substring(@NextFilter,@subPos+1, len(@NextFilter))) 

     SET @Filters = substring(@Filters,@pos+1,len(@Filters)) 
     SET @pos = charindex('~',@Filters) 
    END 

我的數據存儲在一個非常通用的方式,使一個「記錄」可能是這樣的

ContainerModelEntityId DataContainerId ModelEntityId ValueText 
4      17    5    'sunshine company' 
4      17    6    '12999' 
4      17    7    '01/12/2010' 
... 
4      18    5    'moonlight company... 
  • ContainerModelEntityId在容器類型(即企業,個人等)
  • DataContainerId是「行」
  • ModelEntityId是「田」
  • ValueText是實際值

目前下方的SP有傳遞到成SortFieldId它可以說,這是一個5,然後我在我的數據表上進行連接,並對ModelEntityId = 5進行排序。但是現在我也想對我的#filter表中的值進行連接,並且只返回結果值匹配(我已經在下面的代碼中發表了評論,以顯示我認爲邏輯應該去的地方)。但在這一點上,我已經打消了我的想法,因爲設定的邏輯通常會讓我頭疼。任何幫助讚賞。

當前存儲過程

ALTER PROCEDURE [dbo].[GetSortedIndex] 
     @ContainerModelEntityId int, 
     @ParentRecordId   int, 
     @SortFieldId   int, 
     @PageIndex    int, 
     @PageSize    int, 
     @Ascending    bit 
    AS 
    BEGIN 
     -- SET NOCOUNT ON added to prevent extra result sets from 
     -- interfering with SELECT statements. 
     SET NOCOUNT ON; 

     CREATE TABLE #SelectedRecords 
     (  
      ContainerModelEntityId int not null, 
      DataContainerId int not null, 
      DataInstanceId int not null, 
      ParentDataContainerId int null 
     ) 

     DECLARE @LowerBound int, @UpperBound int 

     -- Pagination 
     select @LowerBound = ((@PageIndex) * @PageSize)+1 
     select @UpperBound = (@PageIndex+1) * @PageSize+1 

     IF @Ascending = 1 
     BEGIN 
      INSERT INTO #SelectedRecords 
      SELECT ContainerModelEntityId, 
          DataContainerId, 
          DataInstanceId, 
          ParentDataContainerId 
        FROM 
      ( 
       select di.ModelEntityId as 'ContainerModelEntityId', 
          dc.DataContainerId, 
          di.DataInstanceId, 
          dv.ModelEntityId, 
          dc.ParentDataContainerId, 
        ROW_NUMBER() OVER (ORDER BY dv.ValueText) AS row 
       from datacontainer dc 
       inner join dataInstance di 
          on dc.DataContainerId = di.DataContainerId 
         //some funky join on #Filter table to go here 
         left outer join dataValue dv 
          on di.DataInstanceId = dv.DataInstanceId 
          and [email protected] 
       where ISNULL(dc.ParentDataContainerId,0) 
           = ISNULL(@ParentRecordId,0) 
          and di.IsCurrent = 1 
          and di.ModelEntityId = @ContainerModelEntityId 
      ) tbl 
       WHERE tbl.row >= @LowerBound AND 
       tbl.row < @UpperBound 
    END 
    ELSE 
    BEGIN 
     INSERT INTO #SelectedRecords 
     SELECT ContainerModelEntityId, DataContainerId, 
       DataInstanceId, ParentDataContainerId 
     FROM 
     ( 
      select di.ModelEntityId as 'ContainerModelEntityId', 
       dc.DataContainerId, di.DataInstanceId, 
       dv.ModelEntityId, dc.ParentDataContainerId, dv.ValueText, 
      ROW_NUMBER() OVER (ORDER BY dv.ValueText DESC) AS row 
     from datacontainer dc 
     inner join dataInstance di 
       on dc.DataContainerId = di.DataContainerId 
      //some funky join on #Filter table to go here 
     left outer join dataValue dv 
       on di.DataInstanceId = dv.DataInstanceId 
        and [email protected] 
     where ISNULL(dc.ParentDataContainerId,0) = ISNULL(@ParentRecordId,0) 
        and di.IsCurrent = 1 
        and [email protected] 
     ) tbl 
     WHERE tbl.row >= @LowerBound AND 
       tbl.row < @UpperBound 
    END 

    DECLARE @Count int 
    SELECT @Count = (SELECT COUNT(*) FROM DataContainer dc 
    INNER JOIN DataInstance di ON di.DataContainerId = dc.DataContainerId 
    WHERE di.ModelEntityId = @ContainerModelEntityId 
    AND ISNULL(dc.ParentDataContainerId,0) = ISNULL(@ParentRecordId,0) 
    AND di.IsCurrent=1) 

    SELECT ContainerModelEntityId, DataContainerId, 
      ParentDataContainerId, 
      isnull(dv.ModelEntityId, @sortFieldId) as 'ModelEntityId', 
      dv.ValueText, 
      @Count [TotalRecords] 
    FROM #SelectedRecords sr 
    left outer join dataValue dv ON sr.DataInstanceId = dv.DataInstanceId 

END 

回答

0

確定,得到的東西現在要

ALTER PROCEDURE [dbo].[GetSortedIndex] 
@ContainerModelEntityId int, 
@ParentRecordId   int, 
@SortFieldId   int, 
@PageIndex    int, 
@PageSize    int, 
@Ascending    bit = 1, 
@Filters    varchar(max) = null 

AS BEGIN - SET NOCOUNT ON加入是爲了避免額外的結果集 - 與干擾SELECT語句。 SET NOCOUNT ON;

DECLARE @NextFilter NVARCHAR(100) 
DECLARE @Pos INT 
DECLARE @SubPos INT 
DECLARE @NextPos INT 

CREATE TABLE #Filters 
(  
    ModelEntityId int not null, 
    ValueText nvarchar(max) 
) 

CREATE TABLE #SelectedRecords 
( row int,  
    ContainerModelEntityId int not null, 
    DataContainerId int not null, 
    DataInstanceId int not null, 
    ParentDataContainerId int null 
) 

DECLARE @LowerBound int, @UpperBound int 

-- Pagination 
select @LowerBound = ((@PageIndex) * @PageSize)+1 
select @UpperBound = (@PageIndex+1) * @PageSize+1 

IF (Len(@Filters)>0) 
BEGIN 
    SET @Filters = @Filters + '~' 
    SET @Pos = charindex('~',@Filters) 
    WHILE (@pos <> 0) 
    BEGIN 
     SET @NextFilter = substring(@Filters,1,@Pos - 1) 
     SET @SubPos = charindex('=',@NextFilter) 
     insert into #Filters (ModelEntityId, ValueText) Values (substring(@NextFilter, 1, @SubPos-1),substring(@NextFilter,@subPos+1, len(@NextFilter))) 
     SET @Filters = substring(@Filters,@pos+1,len(@Filters)) 
     SET @pos = charindex('~',@Filters) 
    END  

    INSERT INTO #SelectedRecords  
     select row, 
       ContainerModelEntityId, 
       DataContainerId, 
       DataInstanceId, 
       ParentDataContainerId   
     from 
     (
      select row_number() over (order by dv.valuetext) as row, 
        filtered.ContainerModelEntityId, 
        filtered.ParentDataContainerId, 
        filtered.DataContainerId, 
        filtered.DataInstanceId      
      from dataValue dv 
      join 
      (
       select dc.ModelEntityId as 'ContainerModelEntityId', 
         di.DataInstanceId, 
         di.DataContainerId, 
         dc.ParentDataContainerId 
       from datainstance di 
        join datavalue dv on di.Datainstanceid = dv.datainstanceid 
        join datacontainer dc on dc.DataContainerId = di.datacontainerId 
        join #filters f on dv.ModelEntityId = f.ModelEntityId and f.ValueText = dv.ValueText 
       where ISNULL(dc.ParentDataContainerId,0) = ISNULL(null,0) and di.IsCurrent = 1 and di.ModelEntityId = @ContainerModelEntityId 
       group by dc.ModelEntityId, dc.ParentDataContainerId, di.DataInstanceId, di.DataContainerId 
       having (count(di.DataInstanceId) = (select count(ModelEntityId) from #Filters)) 
      ) 
      filtered on filtered.dataInstanceId = dv.dataInstanceId 
      where dv.ModelEntityId = @SortFieldId 
     ) tbl 
     WHERE row >= @LowerBound AND 
       row < @UpperBound 
END 
ELSE 
BEGIN 
    INSERT INTO #SelectedRecords 
    SELECT Row, ContainerModelEntityId, DataContainerId, DataInstanceId, ParentDataContainerId 
    FROM 
    ( 
     select ROW_NUMBER() OVER (ORDER BY dv.ValueText) AS row, 
       di.ModelEntityId as 'ContainerModelEntityId', 
       dc.DataContainerId, 
       di.DataInstanceId, 
       dv.ModelEntityId, 
       dc.ParentDataContainerId   
     from datacontainer dc 
      inner join dataInstance di on dc.DataContainerId = di.DataContainerId 
      left outer join dataValue dv on di.DataInstanceId = dv.DataInstanceId and [email protected] 
     where (@ParentRecordId is NULL or ISNULL(dc.ParentDataContainerId,0) = ISNULL(@ParentRecordId,0)) and 
       di.IsCurrent = 1 and [email protected] 
    ) tbl 
    WHERE tbl.row >= @LowerBound AND 
      tbl.row < @UpperBound 
END 


DECLARE @Count int 
SELECT @Count = (SELECT COUNT(*) FROM DataContainer dc 
INNER JOIN DataInstance di ON di.DataContainerId = dc.DataContainerId 
WHERE [email protected] AND ISNULL(dc.ParentDataContainerId,0) = ISNULL(@ParentRecordId,0) AND di.IsCurrent=1) 

    SELECT ContainerModelEntityId, DataContainerId, ParentDataContainerId, isnull(dv.ModelEntityId, @sortFieldId) as 'ModelEntityId', dv.ValueText, 
     @Count [TotalRecords] FROM 
    #SelectedRecords sr 
    left outer join dataValue dv ON sr.DataInstanceId = dv.DataInstanceId 
    ORDER BY 
    CASE 
     WHEN @Ascending = 1 THEN (RANK() OVER (ORDER BY sr.row ASC)) 
     WHEN @Ascending = 0 THEN (RANK() OVER (ORDER BY sr.row DESC)) 
    END 

END