Если вам абсолютно необходимо использовать функцию (как вы подразумеваете, это ограничение вашего ETL-инструмента), вы можете указать ее OPTION
как часть табличной функции с несколькими утверждениями, например что-то вроде этого:
CREATE FUNCTION dbo.udf_MyFunction ( @StartID INT )
RETURNS @tv TABLE
(
id INT
)
AS
BEGIN
WITH Episodes( xlevel, PersonID, EventID, EpisodeID, StartDT, EndDT ) AS (
-- Anchor case - the first EventID for each person.
SELECT 1 AS xlevel, PersonID, EventID, @StartID, StartDT, EndDT
FROM dbo.EventTable
WHERE EventID = @StartID
UNION ALL
SELECT xlevel + 1, et.PersonID, et.EventID, c.EventID + 1, et.StartDT, et.EndDT
FROM Episodes c
INNER JOIN dbo.EventTable et ON c.PersonID = et.PersonID
AND et.EventID = c.EventID + 1
--WHERE c.EventID <= (@StartID + 99)
)
INSERT INTO @tv
SELECT PersonID
FROM Episodes
OPTION ( MAXRECURSION 1000 )
RETURN
END
GO
Это также сработало для меня, когда обернулось в представление, как вы предлагаете ваши инструменты ETL. Нет никакого способа изменить это в масштабе всей системы, но поскольку рекурсия может быть неэффективной, это, вероятно, хорошая вещь. Вы не можете указать подсказку запроса (используя OPTION
) в теле встроенной табличной функции, как в вашем примере.
Подумайте о том, чтобы изменить свой процесс, чтобы обходить иерархию только один раз, когда вы получаете свои эпизоды и сохраняете выходные данные в реляционной таблице. Вы можете использовать хранимый процесс, чтобы не делать этого ограничения.
Я также думаю, что в вашем коде может быть ошибка: если ваш CTE включается в personId и рекурсивно в eventId, eventId 101 будет представлен дважды, я думаю, как дубликат. Возможно, я неправильно истолковал ваш код, дайте мне знать, что вы думаете.
НТН