我具有以下按预期工作的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 Docs中没有发现任何有关此“特殊”案例的提示。
答案 0 :(得分:1)
查询提示总是出现在查询的最后。因此,只需将Md=[0.000000 0.0000 340.216815
0.000000 1.5625 570.718050
0.000000 4.6875 769.256473
6.500000 0.0000 331.115127
6.500000 1.5370 510.419428
6.500000 4.6108 719.346166
13.000000 0.0000 325.858265
13.000000 1.5114 426.599681
13.000000 4.5341 671.896040
19.500000 0.0000 330.567837
19.500000 1.4702 383.856624
19.500000 4.4105 643.279493
26.000000 0.0000 333.606362
26.000000 1.4602 381.784469
26.000000 4.3807 648.680568];
移至最后一个半冒号之前即可。
// start the session
session_start();
$bShowBanner = true;
if(isset($_SESSION['BannerShown'])){
$bShowBanner = false;
}else{
$_SESSION['BannerShown'] = true;
}
?>
<div class="homeslidermain" style="display:<?php echo ($bShowBanner ? 'block' : 'none'); ?>">
<?php putRevSlider("typewriter-effect", "homepage") ?>
</div>
答案 1 :(得分:0)
您可以使用具有CTE结构的表变量来存储结果,这些结果稍后将在merge
语句中使用:
declare @tmp table (
[Datum] date,
[Year] int,
[Month] int,
[IsoWeek] int,
[YearMonth] int,
[SelID] int,
[WeekYear] int
)
然后您可以使用MAXRECURSION 0
将CTE写入表变量中来执行CTE:
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
)
insert into @tmp
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)
现在,您应该可以将表SYS_LIST_DATEHLP
与表变量@tmp
合并:
MERGE INTO SYS_LIST_DATEHLP AS Target
USING (
SELECT
[Datum]
,[Year]
,[Month]
,[IsoWeek]
,[YearMonth]
,[SelID]
,[WeekYear]
FROM @tmp
)
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);