如何使用声明创建视图
How to create view with a declare
我需要根据我编写的查询创建一个视图。这个问题是这个包含一个声明和一个CTE。现在我知道 CTE 应该没问题,但声明会引发问题。部分代码为:
CREATE OR ALTER VIEW vw_NonApprovedTests AS
DECLARE @StartDate DATETIME = (SELECT MIN(ActionOn) FROM WFD)
DECLARE @EndDate DATETIME = GETDATE();
WITH OrderDays as
(
SELECT
CalendarDate = @StartDate
UNION ALL
SELECT
CalendarDate = DATEADD(MONTH, 1, CalendarDate)
FROM
OrderDays WHERE DATEADD (MONTH, 1, CalendarDate) <= @EndDate
),
Calendar AS
(
SELECT
EndOfMonth = EOMONTH (CalendarDate)
FROM
OrderDays
)
SELECT etc.......
它给出的错误是:
Msg 156, Level 15, State 1, Procedure vw_NonApprovedOrWithdrawIntegrityTests, Line 6 [Batch Start Line 0]
Incorrect syntax near the keyword 'DECLARE'.
我用它来计算其余查询中的某些结果。这些结果需要放在一个视图中,以便它们可以在 PowerBI 中用于仪表板。有没有办法让我完成这项工作?
正如我在评论中提到的,您不能在 VIEW
中定义变量。 VIEW
必须由导致 SELECT
的 单个 语句组成;因此不能将变量定义为 2+ 语句。
正如我还提到的,我建议不要使用 rCTE 来创建日历。它们是 slow,如果您的结果需要超过 100 行,如果您没有在 OPTION
子句中定义 MAXRECURSION
值,则很可能会出错外部查询。
而是使用内联计数或日历 table 来获取所需的日期。我这里用的是理货,个人比较推荐后者(虽然没有样本数据,这个是未经测试的):
CREATE OR ALTER VIEW vw_NonApprovedOrWithdrawIntegrityTests AS
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT 0 AS I
UNION ALL
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2, N N3), --1,000 rows
Calendar AS(
SELECT TOP (SELECT DATEDIFF(MONTH,MIN(ActionOn),GETDATE()) FROM dbo.WorkFlowDetails)
EOMONTH(DATEADD(MONTH,T.I,WFD.ActionOn)) AS EndOfMonth
FROM Tally T
CROSS APPLY (SELECT MIN(ActionOn) FROM dbo.WorkFlowDetails) WFD)
SELECT ...;
您可以通过将变量替换为分配它们的语句来做到这一点,即
WITH OrderDays AS
(
SELECT CalendarDate = MIN(ActionOn)
FROM WorkFlowDetails
UNION ALL
SELECT CalendarDate = DATEADD(MONTH, 1, CalendarDate)
FROM OrderDays
WHERE DATEADD (MONTH, 1, CalendarDate) <= GETDATE()
), ....
正如评论中所建议的那样,Calendar table 将使这变得更容易,性能也更高:
SELECT Date
FROM dbo.Calendar
WHERE Date >= (SELECT MIN(ActionOn) FROM WorkFlowDetails)
AND Date <= GETDATE()
我需要根据我编写的查询创建一个视图。这个问题是这个包含一个声明和一个CTE。现在我知道 CTE 应该没问题,但声明会引发问题。部分代码为:
CREATE OR ALTER VIEW vw_NonApprovedTests AS
DECLARE @StartDate DATETIME = (SELECT MIN(ActionOn) FROM WFD)
DECLARE @EndDate DATETIME = GETDATE();
WITH OrderDays as
(
SELECT
CalendarDate = @StartDate
UNION ALL
SELECT
CalendarDate = DATEADD(MONTH, 1, CalendarDate)
FROM
OrderDays WHERE DATEADD (MONTH, 1, CalendarDate) <= @EndDate
),
Calendar AS
(
SELECT
EndOfMonth = EOMONTH (CalendarDate)
FROM
OrderDays
)
SELECT etc.......
它给出的错误是:
Msg 156, Level 15, State 1, Procedure vw_NonApprovedOrWithdrawIntegrityTests, Line 6 [Batch Start Line 0]
Incorrect syntax near the keyword 'DECLARE'.
我用它来计算其余查询中的某些结果。这些结果需要放在一个视图中,以便它们可以在 PowerBI 中用于仪表板。有没有办法让我完成这项工作?
正如我在评论中提到的,您不能在 VIEW
中定义变量。 VIEW
必须由导致 SELECT
的 单个 语句组成;因此不能将变量定义为 2+ 语句。
正如我还提到的,我建议不要使用 rCTE 来创建日历。它们是 slow,如果您的结果需要超过 100 行,如果您没有在 OPTION
子句中定义 MAXRECURSION
值,则很可能会出错外部查询。
而是使用内联计数或日历 table 来获取所需的日期。我这里用的是理货,个人比较推荐后者(虽然没有样本数据,这个是未经测试的):
CREATE OR ALTER VIEW vw_NonApprovedOrWithdrawIntegrityTests AS
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT 0 AS I
UNION ALL
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2, N N3), --1,000 rows
Calendar AS(
SELECT TOP (SELECT DATEDIFF(MONTH,MIN(ActionOn),GETDATE()) FROM dbo.WorkFlowDetails)
EOMONTH(DATEADD(MONTH,T.I,WFD.ActionOn)) AS EndOfMonth
FROM Tally T
CROSS APPLY (SELECT MIN(ActionOn) FROM dbo.WorkFlowDetails) WFD)
SELECT ...;
您可以通过将变量替换为分配它们的语句来做到这一点,即
WITH OrderDays AS
(
SELECT CalendarDate = MIN(ActionOn)
FROM WorkFlowDetails
UNION ALL
SELECT CalendarDate = DATEADD(MONTH, 1, CalendarDate)
FROM OrderDays
WHERE DATEADD (MONTH, 1, CalendarDate) <= GETDATE()
), ....
正如评论中所建议的那样,Calendar table 将使这变得更容易,性能也更高:
SELECT Date
FROM dbo.Calendar
WHERE Date >= (SELECT MIN(ActionOn) FROM WorkFlowDetails)
AND Date <= GETDATE()