我有一个存储过程,可以获取项目列表,排序并应用分页 但是我还需要添加过滤功能。所以我想做的是传递一串过滤器 比如“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...
目前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 dv.ModelEntityId=@SortFieldId
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 dv.ModelEntityId=@SortFieldId
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
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 :(得分:0)
好的,现在有所收获
ALTER PROCEDURE [dbo].[GetSortedIndex]
@ContainerModelEntityId int,
@ParentRecordId int,
@SortFieldId int,
@PageIndex int,
@PageSize int,
@Ascending bit = 1,
@Filters varchar(max) = null
AS 开始 - 添加SET NOCOUNT ON以防止出现额外的结果集 - 干扰SELECT语句。 设置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 dv.ModelEntityId=@SortFieldId
where (@ParentRecordId is NULL or 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
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
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