Как в переменную поместить список? Заносится только последняя запись, а мне нужен весь список MSSQL
Выполняю задание по T-SQL: Процедура, вызывающая вложенную процедуру, которая подсчитывает среднее количество часов в год по дисциплинам, и выдающая список дисциплин с количеством часов в год меньше среднего
Вложенная процедура:
create proc p4_1 @avgH int output
as
begin
select @avgH = avg(Количество_часов)
from Учебный_план join Преподавание on Учебный_план.Код_Предмета=Преподавание.Код_Предмета
join Преподаватель on Преподавание.Id_Преподавателя=Преподаватель.Id_Преподавателя
group by Преподавание.Id_Преподавателя
end
Результат:
основная процедура:
create proc p4
as
begin
declare @Hour int
exec p4_1 @avgH=@Hour output
select Дисциплина from Учебный_план
where Количество_часов<@Hour
end
Результат выдает неверный, так как в переменную @avgH(процедура p4_1) записывается только последняя запись(65), как мне сделать так, чтобы сравнивалось со всем спискам и подбирало дисциплины исходя из всего списка, а не сравнивая с 65 часами.
Ответы (1 шт):
Вам нужно вернуть массив из первой хранимой процедуры. Это может быть XML или JSON.
Попробуйте следующий концептуальный пример. Он будет работать, начиная с SQL Server 2005 и новее.
CTE делает то, что должна делать ваша первая хранимая процедура. Он возвращает тип данных XML со всеми необходимыми данными. После этого мы конвертируем XML в реляционный формат и с помощью INNER JOIN отфильтровываем записи в основной таблице.
SQL
-- DDL and sample data population, start
DECLARE @tbl_averages TABLE (avg_hour INT);
INSERT INTO @tbl_averages VALUES
(126),
(144),
(108);
DECLARE @tbl_studyPlan TABLE (ID INT IDENTITY PRIMARY KEY, study_hour INT);
INSERT INTO @tbl_studyPlan (study_hour) VALUES
(90),
(100),
(770);
-- DDL and sample data population, end
;WITH rs (xmldata)AS
(
SELECT * FROM @tbl_averages
FOR XML PATH(''), TYPE, ROOT('root')
)
SELECT DISTINCT studyPlan.*
FROM @tbl_studyPlan AS studyPlan INNER JOIN
(SELECT avg_hour = c.value('.', 'INT')
FROM rs CROSS APPLY xmldata.nodes('/root/avg_hour/text()') AS t(c)
) AS seq
ON studyPlan.study_hour < seq.avg_hour;
Результат
+----+------------+
| ID | study_hour |
+----+------------+
| 1 | 90 |
| 2 | 100 |
+----+------------+
