2010-08-31 33 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管理器中执行完全相同的查询。我的猜测是你会得到完全一样的结果。

相关问题