Aquí es lo que tengo como VBScript Subrutina:¿Es posible recurrir a un procedimiento almacenado recursivamente en SQL Server?
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
¿Hay alguna forma de convertir esto en un procedimiento almacenado, ya que tiene la llamada recursiva en la subrutina?
Aquí es lo que he intentado ...
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
pero me da el siguiente error al procedimiento almacenado que se llama ... Un cursor con el mismo nombre 'TableCursor' ya existe.
Supongo que su error se produce porque la llamada recursiva se realiza antes de que el cursor 'TableCursor' esté cerrado. ¿Sería posible darle al cursor un nombre dinámico (quizás 'TableCursorN', donde N es la profundidad de la recursión? ¿Tendría que hacer eso como un parámetro extra)? – FrustratedWithFormsDesigner
El problema no es la recursión, que sin duda está permitida (http://msdn.microsoft.com/en-us/library/aa175801(SQL.80).aspx), es que está utilizando un nombre de cursor estático. No sé lo suficiente sobre los cursores en los servidores MS SQL para publicar esto como una respuesta, sin embargo, ya que * tendría * que decir cómo usar un cursor en esta situación para ser útil. :-) –