Rya*_*yan 11 sql-server recursion stored-procedures cursor
以下是我作为VBScript子例程的内容:
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
Run Code Online (Sandbox Code Playgroud)
无论如何将它转换为存储过程,因为它在子例程中得到了递归调用?
这是我试过的......
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
Run Code Online (Sandbox Code Playgroud)
但是,当调用该存储过程时,我收到以下错误...已存在具有相同名称"TableCursor"的游标.
Blo*_*ard 40
您可以指定LOCAL
游标,如下所示:
DECLARE TableCursor CURSOR LOCAL FOR
SELECT ...
Run Code Online (Sandbox Code Playgroud)
至少在SQL Server 2008 R2(我的机器)中,这允许您递归调用sproc而不会遇到"Cursor already exists"错误.
问题是,当您的游标不是全局游标时,它是一个会话游标.由于您正在进行递归,即使每次迭代都在新的proc范围内创建游标,它们也会同时在同一个PID(连接)中创建,从而发生冲突.
您需要根据在递归期间不会再现的某些条件,在过程的每次迭代中生成唯一的游标名称.
或者,最好找到一种方法,使用set逻辑执行所需操作,并使用递归CTE处理任何必要的递归.
归档时间: |
|
查看次数: |
30356 次 |
最近记录: |