Hier ist, was ich als VBScript-Unterroutine haben:Ist eine rekursiv aufgerufene gespeicherte Prozedur in SQL Server möglich?
sub buildChildAdminStringHierarchical(byval pAdminID, byref adminString)
set rsx = conn.execute ("select admin_id from administrator_owners where admin_id not in (" & adminString & ") and owner_id = " & pAdminID)
do while not rsx.eof
adminString = adminString & "," & rsx(0)
call buildChildAdminStringHierarchical(rsx(0),adminString)
rsx.movenext
loop
end sub
Gibt es trotzdem, dies in eine gespeicherte Prozedur zu drehen, da sie den rekursiven Aufruf in der Unterroutine hat?
Hier ist, was ich versucht habe ...
CREATE PROCEDURE usp_build_child_admin_string_hierarchically
@ID AS INT,
@ADMIN_STRING AS VARCHAR(8000),
@ID_STRING AS VARCHAR(8000) OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @index int;
DECLARE @length int;
DECLARE @admin_id int;
DECLARE @new_string varchar(8000);
SET @index = 1;
SET @length = 0;
SET @new_string = @ADMIN_STRING;
CREATE TABLE #Temp (ID int)
WHILE @index <= LEN(@new_string)
BEGIN
IF CHARINDEX(',', @new_string, @index) = 0
SELECT @length = (LEN(@new_string) + 1) - @index;
ELSE
SELECT @length = (CHARINDEX(',', @new_string, @index) - @index);
SELECT @admin_id = CONVERT(INT,SUBSTRING(@new_string, @index, @length));
SET @index = @index + @length + 1;
INSERT INTO #temp VALUES(@admin_id);
END
DECLARE TableCursor CURSOR FOR
SELECT Admin_ID FROM Administrator_Owners WHERE Admin_ID NOT IN (SELECT ID FROM #temp) AND Owner_ID = @ID;
OPEN TableCursor;
FETCH NEXT FROM TableCursor INTO @admin_id;
WHILE @@FETCH_STATUS = 0
BEGIN
IF LEN(@ID_STRING) > 0
SET @ID_STRING = @ID_STRING + ',' + CONVERT(VARCHAR, @admin_id);
ELSE
SET @ID_STRING = CONVERT(VARCHAR, @admin_id);
EXEC usp_build_child_admin_string_hierarchically @admin_id, @ID_STRING, @ID_STRING;
FETCH NEXT FROM TableCursor INTO @admin_id;
END
CLOSE TableCursor;
DEALLOCATE TableCursor;
DROP TABLE #temp;
END
GO
Aber ich folgende Fehlermeldung erhalten, wenn die gespeicherte Prozedur ... Ein Cursor mit dem gleichen Namen ‚TableCursor‘ existiert bereits genannt wird.
Ich vermute, dass Ihr Fehler auftritt, weil der rekursive Aufruf erfolgt, bevor der Cursor "TableCursor" geschlossen ist. Wäre es möglich, dem Cursor einen dynamischen Namen zu geben (vielleicht 'TableCursorN', wobei N die Tiefe der Rekursion ist - müssten Sie das als zusätzlichen Parameter machen)? – FrustratedWithFormsDesigner
Das Problem ist nicht Rekursion, die sicherlich erlaubt ist (http://msdn.microsoft.com/en-us/library/aa175801(SQL.80).aspx), es ist, dass Sie einen statischen Cursor-Namen verwenden. Ich weiß nicht genug über Cursor in MS SQL-Servern, um dies als Antwort zu posten, da es * hätte * zu sagen, wie man einen Cursor in dieser Situation benutzt, um nützlich zu sein! :-) –