2010-08-31 28 views
3

我有遞歸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 
+0

所以,如果我忽略錯誤,只是使用它似乎工作,但我仍然擔心錯誤。 – Jeff 2010-08-31 21:06:45

回答

1

當你說:

還記得SQL管理員運行正常工作

WHA t值是否用於參數測試? VS中的錯誤可能是由設計者的調用引起的。值得檢查的是,您使用與設計者使用的參數相同的參數調用該過程。

嘗試使用SQL事件探查器來跟蹤SQL調用,並確切地檢查VS傳遞的值。然後您可以從SQL管理器中執行完全相同的查詢。我的猜測是你會得到完全一樣的結果。

相關問題