创建与存储过程相同的功能失败

时间:2016-11-12 03:41:23

标签: sql-server

这是我能够创建的存储过程

eval "$(uru_rt admin install)"

这是我的功能,我试图创建但不能。除了使它成为一个函数之外,它与上面的内容相同。

CREATE PROCEDURE [dbo].[spGetAllStaffCollectiveAttendanceByMonth]
@Month nvarchar(9)
AS
BEGIN

Declare @StartDate DATE,
@EndDate DATE

;WITH CteMonths(n, m) AS(
    SELECT 1, 'January' UNION ALL
    SELECT 2, 'February' UNION ALL
    SELECT 3, 'March' UNION ALL
    SELECT 4, 'April' UNION ALL
    SELECT 5, 'May' UNION ALL
    SELECT 6, 'June' UNION ALL
    SELECT 7, 'July' UNION ALL
    SELECT 8, 'August' UNION ALL
    SELECT 9, 'September' UNION ALL
    SELECT 10, 'October' UNION ALL
    SELECT 11, 'November' UNION ALL
    SELECT 12, 'December'
  )
SELECT @StartDate = DATEADD(MONTH, n - 1, DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)), 
@EndDate = DATEADD(DAY, -1, DATEADD(MONTH, n, DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)))
FROM CteMonths
WHERE m = @month

SELECT
    StaffAttendance.StaffId,
    DATENAME(MONTH, @StartDate) AS [ForMonth], @StartDate AS StartDate, @EndDate AS EndDate,
    (DATEDIFF(dd, @StartDate, @EndDate) + 1)-(DATEDIFF(wk, @StartDate, @EndDate) * 1)-(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END) AS TotalWorkingDays,
    SUM(StaffAttendance.AttendanceStatusId) AS TotalDaysWorked
    FROM StaffAttendance 
    WHERE [Date] BETWEEN @StartDate AND @EndDate AND StaffAttendance.AttendanceStatusId = 1 GROUP BY StaffAttendance.StaffId
END


GO

但这就是我得到的

enter image description here

我做错了什么?

1 个答案:

答案 0 :(得分:1)

您已使用内联表值函数的语法,但您有多个语句。

Comparison of inline and multi-statement table-valued functions.

因此,您可以重构使用单个语句(更高性能)或使用该链接中描述的多语句语法(更简单)。

如果你想内联这样做,你可以沿着这些方向做一些事情(请注意,我现在没有SSMS可用,因此可能会出现一些小的语法错误,例如无法匹配的括号):

CREATE FUNCTION [dbo].[funcGetAllStaffCollectiveAttendanceByMonth]
(
@Month nvarchar(9)
)
RETURNS TABLE
AS
RETURN
(
-- The StartDate should be the first day of the month that is passed as a parameter, in the current year.
-- The EndDate should be the last day of the month which the StartDate begins.
WITH cteDates AS (
    SELECT StartDate = Convert(date, Concat('01', @Month, Convert(varchar(4), DatePart(Year, GetDate()))), 106),
    EndDate = DateAdd(Day, -1, 
        DateAdd(Month, 1, 
            Convert(date, Concat('01', @Month, Convert(varchar(4), DatePart(Year, GetDate()))) , 106)
        )
    )
)

SELECT
    Sa.StaffId,
    DATENAME(MONTH, cteDates.StartDate) AS [ForMonth], 
    cteDates.StartDate, 
    cteDates.EndDate,
    (DATEDIFF(dd, cteDates.StartDate, cteDates.EndDate) + 1)-
        (DATEDIFF(wk, cteDates.StartDate, cteDates.EndDate) * 1)-
        (CASE WHEN DATENAME(dw, cteDates.StartDate) = 'Sunday' THEN 1 ELSE 0 END) AS TotalWorkingDays,
    SUM(sa.AttendanceStatusId) AS TotalDaysWorked
  FROM StaffAttendance As sa
  JOIN cteDates ON sa.[Date] BETWEEN cteDates.StartDate AND cteDates.EndDate 
  WHERE sa.AttendanceStatusId = 1 
  GROUP BY 
    Sa.StaffId,
    DATENAME(MONTH, cteDates.StartDate), 
    cteDates.StartDate, 
    cteDates.EndDate,
    (DATEDIFF(dd, cteDates.StartDate, cteDates.EndDate) + 1)-
        (DATEDIFF(wk, cteDates.StartDate, cteDates.EndDate) * 1)-
        (CASE WHEN DATENAME(dw, cteDates.StartDate) = 'Sunday' THEN 1 ELSE 0 END)
END
)