以下是存储过程
ALTER PROCEDURE [dbo].[get_data_Dyna]
{
@param1 varchar(max) = null,
@param2 varchar(max) = null,
@start varchar(max) = null,
@end varchar(max) = null
}
AS
SELECT * from table where
(@param1 IS NULL OR column1 IN (SELECT data FROM dbo.delimited_list_to_table(@param1,',')))
AND (@param2 IS NULL OR column2 IN (SELECT data FROM dbo.delimited_list_to_table(@param2,',')))
AND ....?????
这是如何工作的:
我正在尝试包括其余有望按如下方式工作的参数:
@ start ='0'和@ end ='100':在这种情况下,where子句看起来像这样
...AND val BETWEEN @start AND @end
@ start = '48,60'和@ end = '51,99':在这种情况下,where子句看起来像这样
...AND ((val Between 48 and 51) or (val Between 60 and 99))
@ start = '48,60,75'和@ end = '51,99,203':在这种情况下,where子句看起来像这样
...AND ((val Between 48 and 51) or (val Between 60 and 99) or (val Between 75 and 203))
我无法正确包含上述第二/第三点。我试图动态地编写它,它适用于单个值[点1],但是如何编写点2/3?
非常感谢您的帮助。
答案 0 :(得分:0)
好吧,我认为最好的方法是使用临时表或表变量。 让我们来看一下临时表。
create table #StartEnd (start int not null, end int not null, primary key (start,end))
然后我们使用 dbo.delimited_list_to_table 从@start和@end插入其中。现在,我不确定您是否会执行该操作,因此我将假定值已编号
insert into #StartEnd
select starts.data, ends.data
from dbo.delimited_list_to_table(@start,',') as starts
join dbo.delimited_list_to_table(@end,',') as ends
on starts.index = ends.index
现在我们必须过滤值。两种方法。加入或存在条件
...
join #StartEnd on val between start and end
...
and exists (select 1 from #StartEnd where val between start and end)
希望这会有所帮助
答案 1 :(得分:0)
你去了。评论/解释都在查询中
-- create a sample table
declare @tbl table
(
val int
)
-- put in some sample data
insert into @tbl
values (48), (60), (51), (99), (75), (203)
-- these are the input parameter
declare @start varchar(100),
@end varchar(100)
-- and these are the input value
select @start = '48,60,75',
@end = '51,99,203'
-- the actual query
; with
start_end as
(
-- here i am using [DelimitedSplit8K][1]
select s = s.Item, e = e.Item
from dbo.[DelimitedSplit8K](@start, ',') s
inner join dbo.[DelimitedSplit8K](@end, ',') e
on s.ItemNumber = e.ItemNumber
)
select t.val
from @tbl t
where exists
(
select *
from start_end x
where t.val between x.s and x.e
)
您可以在这里DelimitedSplit8K
答案 2 :(得分:0)
样本输入(根据我们的理解,我们猜测您的数据):
select
* into ##demilit
from (
values
(1 ,'Ger','Ind', 100 )
,(2 ,'Ind',Null, 10 )
,(3 ,'Ger',Null, 24 )
,(4 ,'Ind','Ger', 54 )
,(5 ,'USA','Ind', 56 )
,(6 ,Null,'USA', 75 )-- NULL. But USA is three time came.
,(7 ,'USA','USA', 60 )-- same country with diff val.
,(8 ,'USA','USA', 80 )-- same country with diff val.
) demilit(Id,FromPr,ToPr,Val)
select * from ##demilit
过程(您只需使用它代替您的过程即可):
create PROCEDURE [dbo].[get_data_Dyna]
(
@param1 varchar(max) = null,
@param2 varchar(max) = null,
@start varchar(max) = null,
@end varchar(max) = null
)
AS
begin
select * from ##demilit d
join ( --| Here We check the val btw @start and @end
select distinct s.FinalColumn StartVal --|
, e.FinalColumn EndVal --|
from dbo.WithoutDelimit (@start,',') s --| S means 'Start'
join ( --|
select * from dbo.WithoutDelimit (@end,',') --|
) e on s.id = e.id --| E means 'End'
) se --| se mean StartEnd
on d.val between se.StartVal and se.EndVal --| Here YOUR CONDITION is accomplished
where ( -- | checks whether
frompr in ( -- | column1 in @param1 or not
select FinalColumn from dbo.WithoutDelimit (@param1,',') -- | frompr means, 'column1'
) or @param1 is null -- |
)
and ( -- | checks whether
ToPr in ( -- | column2 in @param2 or not
select FinalColumn from dbo.WithoutDelimit (@param2,',') -- | frompr means, 'column2'
) or @param2 is null -- |
)
end
致电SP
[get_data_Dyna] null,'usa','75','100,' -- 6 row
[get_data_Dyna] 'Ind,Ger',null,'1,15','20,30' --2 and 3 rows are selected.
[get_data_Dyna] 'usa','usa','50,60','55,79'
-- 7 and 8 has same country. But due to Val, 8 has been rejected.
[get_data_Dyna] NULL,'usa','70,60','80,79'
-- 6 and 7 and 8 has been selected. Due to val condition.
功能(从SP调用):
alter function WithoutDelimit ( -- We use one Function for all conditions.
@Parameter varchar (max)
, @demilit varchar (1)
)
returns @FinalTable table (
Id int identity (1,1) -- Auto increament
, FinalColumn varchar (max) -- It returns the values as a column.
) as
begin
;with cte as -- recurrsive cte.
(
select convert (varchar (255), @Parameter + @demilit) con
, convert (varchar (255), @Parameter + @demilit) want
union all
select convert (varchar (255), stuff (con, 1, CHARINDEX (@demilit,con),'') )
, substring (con, 1, CHARINDEX (@demilit,con)-1)
from cte
where con <> ''
) insert into @FinalTable (FinalColumn)
select want from cte
where con <> want
return
end
如果查询需要更新,请回复我们。