TSQL:选择动态WHERE来自另一个表

时间:2012-06-01 13:47:52

标签: tsql sql-server-2005 where-clause

我正在为客户开发统计数据解决方案,现在我需要使用来自另一个表的动态条件选择一些行from a table销售数据(由客户填写,每天都可以更改)。

此外,我需要使用游标执行更多的计算和其他东西,所以这是场景:

DECLARE cRiga CURSOR LOCAL FAST_FORWARD FOR
    -- here i will put the SELECT ...
OPEN cRiga
    FETCH NEXT FROM cRiga INTO @field1, @field2, @field3, ...
    WHILE @@FETCH_STATUS = 0
    BEGIN
        -- do some stuff here ...
        FETCH NEXT FROM cRiga INTO @field1, @field2, @field3, ...
    END
CLOSE cRiga
DEALLOCATE cRiga

这是条件表,我可以在其中找到动态条件(参见colum Completa = 0)

IDIncentive CdMarca CdSettore CdGruppo Completa
----------- ------- --------- -------- -----------
1           COES    NULL      NULL     1
1           DELONG  10        0024     0  <
1           RHOSS   NULL      NULL     1
1           SILE    10        0012     0  <
1           SILE    11        0025     0  <
1           THERMI  NULL      NULL     1
....... more rows ...

为了更清楚,我尝试将许多查询中所需的SQL分解为:

Select Field1, ... from SELLDATA 
where IDIncentive=1 and CdMarca='DELONG' and CdSettore=10 and CdGruppo='0024'
UNION ALL
Select Field1, ... from SELLDATA 
where IDIncentive=1 and CdMarca='SILE' and CdSettore=10 and CdGruppo='0012'
UNION ALL
Select Field1, ... from SELLDATA 
where IDIncentive=1 and CdMarca='SILE' and CdSettore=11 and CdGruppo='0025'

你可以想象我不能这样做,因为客户每天都会改变条件所以我的问题是:

如何创建一个具有所有条件的选择(如上例所示)在游标中使用?有办法吗?

感谢谁能帮助我,如果需要更多信息以便更明确地提出这个问题,请提供建议

3 个答案:

答案 0 :(得分:2)

假设您确实需要一个游标(并且您不需要9次),您可以使用动态SQL和sp_executesql在运行时创建任意游标:

declare @cursor cursor
declare @sql nvarchar(max)
declare @dynamic_part nvarchar(max)
declare @name sysname

set @dynamic_part = 'tables'
set @sql = '
  set @cursor = cursor static for select top (100) name from sys.'+@dynamic_part+'
  open @cursor'

exec sp_executesql @sql, N'@cursor cursor output', @cursor output 
while 1=1 begin
  fetch next from @cursor into @name
  if @@fetch_status <> 0 break
  print @name
end
close @cursor deallocate @cursor

或者,您可以创建临时表,通过动态SQL填充临时表,然后根据临时表定义游标:

declare @cursor cursor
declare @sql nvarchar(max)
declare @dynamic_part nvarchar(max)
declare @name sysname

if object_id('tempdb..#these_things') is not null drop table #these_things
create table #these_things (name sysname)

set @dynamic_part = 'tables'
set @sql = 'insert #these_things (name) select top (100) name from sys.'+@dynamic_part
exec (@sql)

set @cursor = cursor fast_forward for select name from #these_things
open @cursor
while 1=1 begin
  fetch next from @cursor into @name
  if @@fetch_status <> 0 break
  print @name
end
close @cursor deallocate @cursor

这可能有点清洁。

答案 1 :(得分:1)

您可以使用现有的ConditionTable表通过join来过滤SELLDATA:no cursor,no all all。

Select Field1, ... 
  from SELLDATA 
 inner join ConditionTable
    ON SELLDATA.IDIncentive=ConditionTable.IDIncentive 
   and SELLDATA.CdMarca=ConditionTable.CdMarca
   and SELLDATA.CdSettore=ConditionTable.CdSettore
   and SELLDATA.CdGruppo=ConditionTable.CdGruppo
 where ConditionTable.Completa = 0

答案 2 :(得分:0)

我认为子查询可以帮助你。

http://dev.mysql.com/doc/refman/5.1/en/subqueries.html