Создание хранимой процедуры для динамического сводного запроса - PullRequest
0 голосов
/ 12 апреля 2019

Через некоторое время я успешно написал динамический сводный запрос для моей базы данных. Теперь мне нужно преобразовать это в хранимую процедуру. Я спрашиваю ответ напрямую, так как я гораздо меньше знаю о хранимых процедурах. Ниже приведен код и параметры, которые мне нужно передать, находятся в местах ('01 -01-2018 '), ('12 -01-2018'), (''04 | 02' '), (' 'FTE 1 '', '' FTE2 '', '' FTE 3 '')

DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)
SELECT @cols = STUFF(
(
SELECT distinct ',' + QUOTENAME([MONTH]) 
FROM [MY_DB].[dbo].[ACTUAL_BILLABLE_HEADCOUNT] 
WHERE [MONTH] BETWEEN ('01-01-2018') AND ('12-01-2018')
ORDER BY ',' + QUOTENAME([MONTH]) 
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'') 

SET @query = 'SELECT ' + @cols + ' 
FROM 
(
SELECT [MONTH],[MONTH END BILLABLE] 
FROM [MY_DB].[dbo].[ACTUAL_BILLABLE_HEADCOUNT] 
WHERE [CC-LOC] = (''04|02'') AND [FTE/RATE CARD] IN (''FTE 1'',''FTE2'',''FTE 3'')
) x pivot (Sum ([MONTH END BILLABLE]) for [MONTH] in (' + @cols + '))p'
execute(@query)

1 Ответ

0 голосов
/ 13 апреля 2019

Превращение вашего динамического сводного запроса в хранимую процедуру не требует особых изменений:)

Ключ определяет переменные для замены жестко закодированных значений, которые вы хотите передать в хранимую процедуру. Ниже приведена рабочая хранимая процедура (названная usp_MonthEndBillableDynamicPivot):

CREATE PROCEDURE usp_MonthEndBillableDynamicPivot(
    @MonthFrom datetime,
    @MonthTo datetime,
    @CC_LOC nvarchar(10),
    @FTE_RATE_CARD nvarchar(100)
)
AS
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)
SELECT @cols = STUFF(
(
SELECT distinct ',' + QUOTENAME([MONTH]) 
FROM [MY_DB].[dbo].[ACTUAL_BILLABLE_HEADCOUNT] 
WHERE [MONTH] BETWEEN (@MonthFrom) AND (@MonthTo)
ORDER BY ',' + QUOTENAME([MONTH]) 
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'') 

SET @query = 'SELECT ' + @cols + ' 
FROM 
(
SELECT [MONTH],[MONTH END BILLABLE] 
FROM [MY_DB].[dbo].[ACTUAL_BILLABLE_HEADCOUNT] 
WHERE [CC-LOC] = (''' + @CC_LOC + ''') AND [FTE/RATE CARD] IN (' + @FTE_RATE_CARD + ')
) x pivot (Sum ([MONTH END BILLABLE]) for [MONTH] in (' + @cols + '))p'
execute(@query)

Мне пришлось сделать некоторые предположения о типах данных, которые вы имеете в вашей реальной таблице ACTUAL_BILLABLE_HEADCOUNT. Для целей тестирования я создал следующую таблицу в своей собственной тестовой базе данных:

create table ACTUAL_BILLABLE_HEADCOUNT(
    ID int identity(1,1) not null,
    MONTH datetime,
    [MONTH END BILLABLE] money,
    ACTUAL_BILLABLE_HEADCOUNT int,
    [CC-LOC] nvarchar(10),
    [FTE/RATE CARD] nvarchar(100),
    constraint PK_ACTUAL_BILLABLE_HEADCOUNT primary key(ID)
)

и заполнил его следующими данными испытаний (обратите внимание, что я использую нотацию даты по ГГГГ-ММ-ДД ISO, чтобы уменьшить путаницу между датами в США и Великобритании (мое местоположение))

insert into ACTUAL_BILLABLE_HEADCOUNT([MONTH],[MONTH END BILLABLE],ACTUAL_BILLABLE_HEADCOUNT,[CC-LOC],[FTE/RATE CARD])
values ('2018-01-01',10000.00,10,'04|02','FTE 1');

insert into ACTUAL_BILLABLE_HEADCOUNT([MONTH],[MONTH END BILLABLE],ACTUAL_BILLABLE_HEADCOUNT,[CC-LOC],[FTE/RATE CARD])
values ('2018-01-01',20000.00,20,'04|02','FTE 2');

insert into ACTUAL_BILLABLE_HEADCOUNT([MONTH],[MONTH END BILLABLE],ACTUAL_BILLABLE_HEADCOUNT,[CC-LOC],[FTE/RATE CARD])
values ('2018-01-01',30000.00,30,'04|02','FTE 3');

insert into ACTUAL_BILLABLE_HEADCOUNT([MONTH],[MONTH END BILLABLE],ACTUAL_BILLABLE_HEADCOUNT,[CC-LOC],[FTE/RATE CARD])
values ('2018-01-01',40000.00,40,'04|02','FTE 4');

insert into ACTUAL_BILLABLE_HEADCOUNT([MONTH],[MONTH END BILLABLE],ACTUAL_BILLABLE_HEADCOUNT,[CC-LOC],[FTE/RATE CARD])
values ('2018-02-01',10000.00,10,'04|02','FTE 1');

insert into ACTUAL_BILLABLE_HEADCOUNT([MONTH],[MONTH END BILLABLE],ACTUAL_BILLABLE_HEADCOUNT,[CC-LOC],[FTE/RATE CARD])
values ('2018-02-01',20000.00,20,'04|02','FTE 2');

insert into ACTUAL_BILLABLE_HEADCOUNT([MONTH],[MONTH END BILLABLE],ACTUAL_BILLABLE_HEADCOUNT,[CC-LOC],[FTE/RATE CARD])
values ('2018-02-01',30000.00,30,'04|02','FTE 3');

insert into ACTUAL_BILLABLE_HEADCOUNT([MONTH],[MONTH END BILLABLE],ACTUAL_BILLABLE_HEADCOUNT,[CC-LOC],[FTE/RATE CARD])
values ('2018-02-01',40000.00,40,'04|02','FTE 4');

Обратите внимание, что я добавил дополнительное значение 'FTE 4', которое я использовал для проверки динамического характера всего этого!

При всем вышеперечисленном хранимая процедура может быть выполнена:

declare
    @MonthFrom datetime = '2018-01-01',
    @MonthTo datetime = '2018-12-01',
    @CC_LOC nvarchar(10) = '04|02',
    @FTE_RATE_CARD nvarchar(100) = '''FTE 1'',''FTE2'',''FTE 3'',''FTE 4'''
;

exec usp_MonthEndBillableDynamicPivot @MonthFrom, @MonthTo, @CC_LOC, @FTE_RATE_CARD;

со следующим результатом:

Example Results

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...