我是存储过程的新手,我正在尝试为学校项目创建一个。我写的SQL语句我想要做什么,只是把它转换成一个存储过程(可能是一个坏黑客的工作,但我们的时间不多了,并有一大堆其他的事情要做)。我们正在使用aspnet Membership Services和整个内置数据库。
我想做什么 我正在使用1个表(TimesheetEntry)。我想所有的全体员工的时间表,汇总每个工作日的小时到达小时/周,并重复这一过程,在过去的4周(以下week1-week4),并在过去的4个月(MONTH1-month4)以下。我使用嵌套的select语句来做到这一点。
以下是完整的错误消息:
错误217:超出最大存储过程,函数,触发器或视图嵌套级别(限制32)。
以下是完整的存储过程:
CREATE PROCEDURE sp_GetTimesheetSummaryReport2
@dateFor DATETIME
AS
SELECT CONVERT(VARCHAR, DATEADD(DAY, -7, GETDATE()), 111) AS startDate,
CONVERT(VARCHAR, GETDATE(), 111) AS currentDate,
projId, wpId, empId,
(
SELECT (SUM(mon) + Sum(tue) + Sum(wed) + Sum(thu) + SUM(fri) + SUM(sat) + SUM(sun)) AS Week
FROM TimesheetEntry
WHERE empId = t.empId AND tsDate BETWEEN @dateFor AND DATEADD(DAY, -7, @dateFor)
GROUP BY empId, projId, wpId
) AS week1,
(
SELECT (SUM(mon) + Sum(tue) + Sum(wed) + Sum(thu) + SUM(fri) + SUM(sat) + SUM(sun)) AS Week
FROM TimesheetEntry
WHERE empId = t.empId AND tsDate BETWEEN DATEADD(DAY, -7, @dateFor) AND DATEADD(DAY, -14, @dateFor)
GROUP BY empId, projId, wpId
) AS week2,
(
SELECT (SUM(mon) + Sum(tue) + Sum(wed) + Sum(thu) + SUM(fri) + SUM(sat) + SUM(sun)) AS Week
FROM TimesheetEntry
WHERE empId = t.empId AND tsDate BETWEEN DATEADD(DAY, -14, @dateFor) AND DATEADD(DAY, -21, @dateFor)
GROUP BY empId, projId, wpId
) AS week3,
(
SELECT (SUM(mon) + Sum(tue) + Sum(wed) + Sum(thu) + SUM(fri) + SUM(sat) + SUM(sun)) AS Week
FROM TimesheetEntry
WHERE empId = t.empId AND tsDate BETWEEN DATEADD(DAY, -21, @dateFor) AND DATEADD(DAY, -28, @dateFor)
GROUP BY empId, projId, wpId
) AS week4,
(
SELECT (SUM(mon) + Sum(tue) + Sum(wed) + Sum(thu) + SUM(fri) + SUM(sat) + SUM(sun)) AS Month
FROM TimesheetEntry
WHERE empId = t.empId AND MONTH(tsDate) = MONTH(@dateFor)
GROUP BY empId, projId, wpId
) AS month1,
(
SELECT (SUM(mon) + Sum(tue) + Sum(wed) + Sum(thu) + SUM(fri) + SUM(sat) + SUM(sun)) AS Month
FROM TimesheetEntry
WHERE empId = t.empId AND MONTH(tsDate) = MONTH(DATEADD(MONTH, -1, @dateFor))
GROUP BY empId, projId, wpId
) AS month2,
(
SELECT (SUM(mon) + Sum(tue) + Sum(wed) + Sum(thu) + SUM(fri) + SUM(sat) + SUM(sun)) AS Month
FROM TimesheetEntry
WHERE empId = t.empId AND MONTH(tsDate) = MONTH(DATEADD(MONTH, -2, @dateFor))
GROUP BY empId, projId, wpId
) AS month3,
(
SELECT (SUM(mon) + Sum(tue) + Sum(wed) + Sum(thu) + SUM(fri) + SUM(sat) + SUM(sun)) AS Month
FROM TimesheetEntry
WHERE empId = t.empId AND MONTH(tsDate) = MONTH(DATEADD(MONTH, -3, @dateFor))
GROUP BY empId, projId, wpId
) AS month4
FROM TimesheetEntry t
GROUP BY t.empId, t.projId, t.wpId
ORDER BY t.projId, t.wpId, t.empId;
EXECUTE sp_GetTimesheetSummaryReport '2011/02/01';
我的问题
为什么我收到此错误?我有没有 超过了堆栈,也有 许多存储 程序/触发器/功能 数据库,我的筑巢太深了吗?
我该如何解决?是我的存储 程序太可怕了,我应该 使用更好的语法重启?
答案 0 :(得分:1)
是否在sp_GetTimesheetSummaryReport2中调用了sp_GetTimesheetSummaryReport?如果是这样,它会做什么?
我认为你在这里进行了一些无限循环调用 - 最终称其自己的嵌套过深。
答案 1 :(得分:1)
好吧,我永远不会在我的一个数据库上允许这个,因为它有相关的子查询,这些子查询逐行运行并且非常慢。它将使用CTE或派生表。
时间表是偶然输入调用其他视图的视图吗?那些可以很容易地达到递归级别,特别是如果被调用多次,你确实将该时间表调用至少我看到的9倍(不包括运行的proc)。
或者你要调用的proc是做什么的?它可能是递归的来源吗?
答案 2 :(得分:0)
我仍然没有看到任何递归。为了简化您的查询,我建议您制作:
totalhours AS (mon + tue + wed + thu + fri + sat + sun) PERSISTED
进入表中的计算列(可能是持久的)。然后,您既不是重复逻辑也不是调用昂贵的用户定义函数,而是获得更好的可维护性。
然后给出:
SELECT (SUM(totalhours)) AS Week
SELECT (SUM(totalhours)) AS Month
我还注意到您的查询包含以下内容:
(
SELECT (SUM(totalhours)) AS Week
FROM TimesheetEntry
WHERE empId = t.empId AND tsDate BETWEEN @dateFor AND DATEADD(DAY, -7, @dateFor)
GROUP BY empId, projId, wpId
) AS week1,
如果有多行,则返回错误 - 即,如果emp具有多个proj或wp。因为您将此视为相关标量子查询。