У меня есть следующий CTE (Microsoft SQL Server 2017), который работает должным образом:
WITH DATE_CTE (Datum)
as
(
SELECT DATEFROMPARTS(1970, 1, 1)
UNION ALL
SELECT DATEADD(Day, 1, DATE_CTE.Datum) FROM DATE_CTE WHERE YEAR(DATE_CTE.Datum) < 2100
)
SELECT DATE_CTE.Datum,
YEAR(DATE_CTE.Datum) as [Year],
MONTH(DATE_CTE.Datum) as [Month],
DATEPART(ISO_WEEK, DATE_CTE.Datum) as IsoWeek,
CAST(YEAR(DATE_CTE.Datum) AS VARCHAR(4)) + IIF(MONTH(DATE_CTE.Datum) < 10, '0' + CAST(MONTH(DATE_CTE.Datum) AS VARCHAR(1)), CAST(MONTH(DATE_CTE.Datum) AS VARCHAR(2))) as YearMonth,
-1 as SelID,
CASE WHEN MONTH(DATE_CTE.Datum) = 1 AND DATEPART(ISO_WEEK, DATE_CTE.Datum) >= 52 THEN YEAR(DATE_CTE.Datum)-1 WHEN MONTH(DATE_CTE.Datum) = 12 AND DATEPART(ISO_WEEK, DATE_CTE.Datum) = 1 THEN YEAR(DATE_CTE.Datum)+1 ELSE YEAR(DATE_CTE.Datum) END as WeekYear
FROM DATE_CTE OPTION (MAXRECURSION 0)
Это вернет следующие данные (с 1970 по 2100 -> 47483 строки данных):
Date Year Month IsoWeek YearMonth SelID WeekYear
---------- ----------- ----------- ----------- --------- ----------- -----------
1970-01-01 1970 1 1 197001 -1 1970
1970-01-02 1970 1 1 197001 -1 1970
1970-01-03 1970 1 1 197001 -1 1970
1970-01-04 1970 1 1 197001 -1 1970
1970-01-05 1970 1 2 197001 -1 1970
1970-01-06 1970 1 2 197001 -1 1970
1970-01-07 1970 1 2 197001 -1 1970
1970-01-08 1970 1 2 197001 -1 1970
1970-01-09 1970 1 2 197001 -1 1970
1970-01-10 1970 1 2 197001 -1 1970
...
Теперь я хотел бы сохранить данные в определенной таблице, в которой могут быть уже некоторые данные (и, что еще хуже, могут иметь некоторые дополнительные поля).Поэтому моя идея заключалась в том, чтобы использовать оператор слияния, подобный следующему:
WITH DATE_CTE (Datum)
as
(
SELECT DATEFROMPARTS(1970, 1, 1)
UNION ALL
SELECT DATEADD(Day, 1, DATE_CTE.Datum) FROM DATE_CTE WHERE YEAR(DATE_CTE.Datum) < 2100
)
MERGE INTO SYS_LIST_DATEHLP AS Target
USING (
SELECT
DATE_CTE.Datum,
YEAR(DATE_CTE.Datum),
MONTH(DATE_CTE.Datum),
DATEPART(ISO_WEEK, DATE_CTE.Datum),
CAST(YEAR(DATE_CTE.Datum) AS VARCHAR(4)) + IIF(MONTH(DATE_CTE.Datum) < 10, '0' + CAST(MONTH(DATE_CTE.Datum) AS VARCHAR(1)),
CAST(MONTH(DATE_CTE.Datum) AS VARCHAR(2))),
-1,
CASE WHEN MONTH(DATE_CTE.Datum) = 1 AND DATEPART(ISO_WEEK, DATE_CTE.Datum) >= 52 THEN YEAR(DATE_CTE.Datum)-1 WHEN MONTH(DATE_CTE.Datum) = 12 AND DATEPART(ISO_WEEK, DATE_CTE.Datum) = 1 THEN YEAR(DATE_CTE.Datum)+1 ELSE YEAR(DATE_CTE.Datum) END
FROM DATE_CTE OPTION (MAXRECURSION 0)
)
AS Source (SYS_DATE, SYS_YEAR, SYS_MONTH, [WEEK], KAPMONAT, SEL_ID, WEEKYEAR)
ON Target.SYS_DATE = Source.SYS_DATE
WHEN MATCHED THEN
UPDATE SET SYS_YEAR = Source.SYS_YEAR, SYS_MONTH = Source.SYS_MONTH, [WEEK] = Source.[WEEK], KAPMONAT = Source.KAPMONAT, SEL_ID = Source.SEL_ID, WEEKYEAR = Source.WEEKYEAR
WHEN NOT MATCHED BY TARGET THEN
INSERT (SYS_DATE, SYS_YEAR, SYS_MONTH, [WEEK], KAPMONAT, SEL_ID, WEEKYEAR)
VALUES (Source.SYS_DATE, Source.SYS_YEAR, Source.SYS_MONTH, Source.[WEEK], Source.KAPMONAT, Source.SEL_ID, Source.WEEKYEAR);
Но это всегда приводит к ошибке со следующей ошибкой:
Неправильный синтаксис рядом с ключевым словом «OPTION».
Опускать OPTION (MAXRECURSION 0)
нельзя, так как CTE делает более 100 рекурсий, а затем SQL просто отвечает:
Оператор завершен.Максимальная рекурсия 100 была исчерпана до завершения оператора.
Где я должен установить OPTION (MAXRECURSION 0)
здесь?Это вообще возможно?К сожалению, я не нашел упоминаний об этом «особом» случае в Документах Microsoft.