2011-03-29 28 views
0

我是新來的存儲過程,並試圖爲學校項目創建一個。我編寫了一條SQL語句,它可以完成我想要的任務,並將其轉換爲存儲過程(可能是一個糟糕的黑客工作,但我們沒時間了,還有其他許多事情要做)。我們使用aspnet Membership Services和整個內置數據庫。aspnet數據庫中的存儲過程錯誤217:超出限制(32)?

我想要做什麼 我正在使用1個表(TimesheetEntry)。我想獲得所有員工的所有時間表,每週工作時間總計小時/周,並在過去4周(下週第1周 - 第4周)和過去4個月(第1 - 第4個月)以下重複此操作。我使用嵌套的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'; 

我的問題

  1. 爲什麼會出現這個錯誤?我是否有 超出堆棧,是否有太多 很多存儲 程序/觸發器/函數在 數據庫中,是我的嵌套太深?

  2. 我該如何解決?我的 存儲過程如此糟糕,我應該使用更好的語法重新啓動 ?

+0

是sp_GetTimesheetSummaryReport哪裏遞歸?因爲,如果TimesheetEntry只是一個表格,我不會在這裏看到任何遞歸。 – 2011-03-29 20:00:53

+0

哦!我的不好,我試着用一個子查詢創建另一個。他們是相關的。兩者都應該說sp_GetTimesheetSummaryReport沒有2. – Katheren 2011-03-29 20:07:10

回答

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。因爲您將其視爲相關的標量子查詢。

+0

邏輯上它不應該。每個員工在給定的一週內只有一個工作包的時間表條目(wpId)。就像我說的那樣,我確實將它作爲常規SQL select語句進行測試。 – Katheren 2011-03-29 20:31:32

+0

@Katheren,根本不需要GROUP BY,因爲每個人都超過一名員工,無論是projId還是wpId。 – 2011-03-29 20:57:08

+0

啊,你是對的,謝謝。我認爲只是有點從以前的嘗試留在那裏。我已經把它拿出來了。 – Katheren 2011-03-29 21:09:53

1

裏面sp_GetTimesheetSummaryReport2到sp_GetTimesheetSummaryReport電話嗎?如果是這樣,它有什麼作用?

我認爲你有一些無限循環的電話在這裏進行 - procs最終稱自己嵌套太深。

+0

我的不好,它應該是sp_GetTimesheetSummaryReport沒有2.我做了第二個函數與一個子查詢來測試它是否是子查詢。 – Katheren 2011-03-29 20:09:53

1

嗯,我永遠不會允許這在我的數據庫之一,因爲它有相關的子查詢逐行運行,並且非常緩慢。它會使用CTE或派生表。

時間表是否偶然出現調用其他視圖的視圖?那些可以很容易地達到遞歸級別,特別是如果調用多個時間,並且您至少調用了9倍的時間表(我不能看到運行的proc)。

或者你所調用的過程是做什麼的?它可能是遞歸的來源嗎?

+0

這是我試圖執行的存儲過程。我已經將它作爲一個常規的SQL語句(只是Select語句的硬編碼日期部分)運行,並且工作正常。時間表不是視圖,它只是原始表格。我完全同意,如果我有更多時間,我會尋找更好的方式(但我們在這門課程只剩下3周)。 – Katheren 2011-03-29 20:22:43

相關問題