2015-12-16 2 views
1

Я пытаюсь создать необязательные параметры в хранимом процессе, в котором я группирую параметры при определенных условиях.Динамический выбор и группировка по заданным параметрам в SQL Server

Например:

SELECT 
    TP.ProductID, 
    case 
     when @passangers='Y'  then (TP.Passangersgroup) 
     when @fareclass='Y'  then (TP.Fareclass) 
     when @ispriorbooking='Y' then (TP.IsPriorBooking) 
    end 
INTO ##B 
FROM ##A TP 
GROUP BY 
    TP.ProductID, 
    case 
     when @passangers='Y'  then (TP.Passangersgroup) 
     when @fareclass='Y'  then (TP.Fareclass) 
     when @ispriorbooking='Y' then (TP.IsPriorBooking) 
    end 

В этом случае, я мог бы выбрать «Y» для любого из 3-х параметров, и я хотел бы добавить, чтобы выбрать заявление и группу по.

Любые идеи?

+0

Этот код предполагает, что первым условием является добавленное поле. Другими словами, невозможно «SELECT» или «GROUP BY» все три поля, используя «CASE». –

ответ

0

Вам нужно сделать это с помощью динамического SQL; что-то вроде:

declare @sql varchar(max) = 'SELECT 
    TP.ProductID, ' + 
    case when @passangers='Y' then 'TP.Passangersgroup' 
    when @fareclass='Y' then 'TP.Fareclass' 
    when @ispriorbooking='Y' then 'TP.IsPriorBooking' 
else ''   
end 
+ ' INTO ##B 
FROM ##A TP' 
--ETC 

Exec(@sql) 

Если вы хотите добавить до трех столбцов, необходимо три регистра заявления:

declare @sql varchar(max) = 'SELECT 
    TP.ProductID, ' + 
    case when @passangers='Y' then 'TP.Passangersgroup' else '' end 
    + case when @fareclass='Y' then 'TP.Fareclass' else '' end 
--ETC. 
+ ' INTO ##B 
FROM ##A TP' 
0

Dynamic SQL будет лучшим выбором, но я бы выяснить, столбец, а затем передать в один столбец как переменную. Меньше шансов пострадать от SQL-инъекций и более читабельны.

DECLARE @passangers CHAR(1), @fareclass CHAR(1), @ispriorbooking CHAR(1) 
SET @passangers='Y' 

DECLARE @SQLCMD NVARCHAR(MAX), @YValue NVARCHAR(1000) 

--set the select and group by field 
SELECT @YValue= 
    case 
     when @passangers='Y' then N'TP.Passangersgroup' 
     when @fareclass='Y' then N'TP.Fareclass' 
     when @ispriorbooking='Y' then N'TP.IsPriorBooking' 
     else NULL 
    end 

IF @YValue IS NOT NULL 
BEGIN 
    SET @SQLCMD=N' 
    SELECT 
    TP.ProductID,'[email protected]+' 
    INTO ##B 
    FROM ##A TP 
    GROUP BY 
     TP.ProductID, '[email protected] 

    PRINT @SQLCMD 
    --EXEC sp_executesql @SQLCMD 
END 
ELSE 
    PRINT 'INVALID PARAMETER PASSED IN' 
0

Вы должны использовать динамический SQL, но случай заявление, упомянутый в Стивом код Mangiameli не будет работать в случае, когда более чем один столбец выбран как «Y». Нижеприведенный код будет работать отлично для нескольких столбцов, выбранных как «Y'-

create procedure proc1 
@passangers varchar(100) = null, 
@fareclass varchar(100) = null, 
@ispriorbooking varchar(100) = null 
as 
begin 
declare @sql nvarchar(100) 
declare @var varchar(100) 

if @passangers = 'y' 
set @var = tp.Passangersgroup + ', ' 
if @fareclass = 'y' 
set @var = @var + TP.Fareclass + ', ' 
if @ispriorbooking = 'y' 
set @var = @var + TP.IsPriorBooking 


set @sql = 'select ' + @var + ' into ##b from ##a as TP group by ' + @var + 'option(recomplile)' 

exec sp_executesql @sql 
end 
+0

Не должны ли утверждения TP быть в заявлении select, чтобы он знал, что такое TP? поэтому весь оператор if должен быть внутри выбранного? –