2010-07-12 2 views
0

J'ai une procédure stockée qui obtient une liste d'éléments, trie et applique la pagination.
Cependant, j'ai aussi besoin d'ajouter un filtrage. Donc ce que je veux faire est passe dans une chaîne de filtres comme « 27 = « Certaines sociétés »; 32 = « Auckland » », et divisé en une table temporaire (voir ci-dessous le code split)Comment passer des filtres dynamiques dans une procédure stockée avec la pagination

de Split proposé Code

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 

Mes données sont stockées de manière très générique si un 'record' pourrait ressembler à ceci

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 est le type de conteneur (c.-à- affaires, personne, etc.)
  • DataContainerId est la « ligne »
  • ModelEntityId est le « champ »
  • Texte valeurs est la valeur réelle

Actuellement, le sp a en dessous d'un SortFieldId qui est passé dans en Et, disons que c'est un 5, je fais ensuite une jointure sur ma table de données et je trie où ModelEntityId = 5. Cependant maintenant je veux aussi faire une jointure sur les valeurs dans ma table #filter et ne retourner que les résultats où le les valeurs correspondent (j'ai placé un commentaire dans le code ci-dessous pour montrer où je pense que la logique devrait aller). Mais à ce stade, j'ai soufflé mon esprit, car la logique de jeu me donne habituellement un mal de tête. Toute aide appréciée.

actuelle procédure stockée

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 

Répondre

0

OK, a obtenu quelque chose maintenant

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 ajouté pour éviter les jeux de résultats supplémentaires de - interférer avec SELECT instructions. 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 

FIN

Questions connexes