简体   繁体   中英

Maximum stored procedure, function, trigger, or view nesting level exceeded in Visual Studio (ado.net) but not in SQL server

I have a problem with a recursive SQL function. The original problem is that I've got a list of employees, each of them has various trainings. Each of these trainings has some pre requirements. For example to have your Class 1 drivers license you must have your Class 5. If I remove the Class 5 I need to check disable the Class 1.

Now as this is a tree with no fixed max depth (actually I stop checking at 10ish) I decided to use recursion. I wrote two stored procedures

[dbo].[spCheckTrainingPreqs]
@PIN int,
@training_id int,
@missingTraining int OUTPUT

and

[dbo].[spCheckTrainingPreqsEmployee] 
@PIN int

Now when I call spCheckTrainingPreqsEmployee with an employee number it creates a cursor for each pin/training_id combo and calls spCheckTrainingPreqs. spCheckTrainingPreqs uses a recursive local cursor to walk the tree.

Now the kicker. It works fine in visual studio

DECLARE @return_value int

EXEC    @return_value = [dbo].[spCheckTrainingPreqsEmployee]
        @PIN = 12673

SELECT  'Return Value' = @return_value

GO

But if I go into visual studio and add it to a table adapter as a stored proc with no return I get the error "Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32)"

I've checked that none of my tables have triggers. The only complexity is that many of the tables have views based off of them with sub queries and even ac# coded custom concatenation function. Remember running it from SQL manager works fine.

Full code for reference

/****** 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;

and

/****** 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

When you say:

Remember running it from SQL manager works fine

what values are you using for the parameters to test? The error in VS is probably caused by a call by the designer. It's worth checking that you are calling the procedure with the same parameters as the designer is using.

Try using SQL Profiler to trace SQL calls and check exactly what values VS is passing. You can then execute the exact same query from within SQL manager. My guess is that you'll get exactly the same result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM