我有遞歸SQL函數的問題。原來的問題是我有一份員工名單,他們每個人都有各種培訓。這些培訓中的每一項都有一些預先要求。例如要獲得您的1類駕駛執照,您必須擁有您的5類。如果我刪除了5類,我需要檢查是否禁用1類。在Visual Studio(ado.net)中超出了最大存儲過程,函數,觸發器或視圖嵌套級別,但在SQL服務器中沒有。
現在,因爲這是一棵沒有固定最大深度的樹(實際上我停檢查10ish)我決定使用遞歸。我寫了兩個存儲過程
[dbo].[spCheckTrainingPreqs]
@PIN int,
@training_id int,
@missingTraining int OUTPUT
和
[dbo].[spCheckTrainingPreqsEmployee]
@PIN int
現在,當我打電話spCheckTrainingPreqsEmployee與僱員數它爲每個引腳/ training_id組合光標並調用spCheckTrainingPreqs。 spCheckTrainingPreqs使用遞歸本地遊標來遍歷樹。
現在踢球。它工作正常,在Visual Studio
DECLARE @return_value int
EXEC @return_value = [dbo].[spCheckTrainingPreqsEmployee]
@PIN = 12673
SELECT 'Return Value' = @return_value
GO
但是,如果我去到Visual Studio中,並將其添加到表適配器沒有返回一個存儲過程我得到的錯誤「最大存儲過程,函數,觸發器或視圖的嵌套水平超過(限制32)「
我檢查過我的表沒有觸發器。唯一的複雜性是,許多表的視圖基於它們的子查詢,甚至是c#編碼的自定義串聯函數。請記住從SQL管理器運行它工作正常。
參考的完整代碼
/****** Object: StoredProcedure [dbo].[spCheckTrainingPreqs] Script Date: 08/31/2010 10:13:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[spCheckTrainingPreqs]
@PIN int,
@training_id int,
@missingTraining int OUTPUT
AS
-- get the Prerequisites
declare @requiresID int
declare CurPrereqs cursor local for SELECT RequiresID FROM TrainingPrerequisites WHERE SourceID = @training_id
SET @missingTraining = 0
OPEN CurPrereqs
FETCH NEXT FROM CurPrereqs INTO @requiresID
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@missingTraining = 0) -- stop when a missing training is found
BEGIN
IF (SELECT count(training_id) FROM employee_training WHERE PIN = @PIN AND training_id = @requiresID GROUP BY training_id) = 1
BEGIN
--they have the training
IF (@@NESTLEVEL < 10) -- we only check 10 levels deep
BEGIN
EXEC spCheckTrainingPreqs @PIN, @requiresID, @missingTraining
UPDATE employee_training SET missingPreReq = @missingTraining WHERE training_id = @training_id and PIN = @PIN;
END
END
ELSE
BEGIN
SET @missingTraining = @requiresID
UPDATE employee_training SET missingPreReq = @missingTraining WHERE training_id = @training_id and PIN = @PIN;
CLOSE CurPrereqs
DEALLOCATE CurPrereqs;
RETURN
END
END
FETCH NEXT FROM CurPrereqs INTO @requiresID
END
CLOSE CurPrereqs
DEALLOCATE CurPrereqs;
和
/****** Object: StoredProcedure [dbo].[spCheckTrainingPreqsEmployee] Script Date: 08/31/2010 10:28:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Create date: 08/31/2010
-- Description: Checks all pre reqs for an employee
-- =============================================
ALTER PROCEDURE [dbo].[spCheckTrainingPreqsEmployee]
@PIN int
AS
BEGIN
SET NOCOUNT ON;
declare @training_id int
declare @missingTraining int
SET @missingTraining = 0
declare CurPrereqsE cursor local for SELECT training_id FROM employee_training WHERE PIN = @PIN
OPEN CurPrereqsE
FETCH NEXT FROM CurPrereqsE INTO @training_id
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC spCheckTrainingPreqs @PIN, @training_id, @missingTraining
FETCH NEXT FROM CurPrereqsE INTO @training_id
END
CLOSE CurPrereqsE
DEALLOCATE CurPrereqsE;
END
所以,如果我忽略錯誤,只是使用它似乎工作,但我仍然擔心錯誤。 – Jeff 2010-08-31 21:06:45