Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Recursive calling COULD be a really nice feature, especially when your output is XML and you need to get XML child nodes that are equal in format as the parent. The workaround is using stored procedures to handle the parent/child relationship, with the drawback of more complicated/redundant code. Say you have:</p> <pre><code>create table Users (UserID int, Name nvarchar(50), ManagerID int null) insert into Users (1, 'Carl', null) insert into Users (2, 'Tom', 1) insert into Users (3, 'John', 1) </code></pre> <p>and</p> <pre><code>create function GetUser(@UserID int) returns XML as begin declare @xml XML SET @xml = ( SELECT [UserID] "User/@UserID" , [Name] "User/@Name" FROM Users WHERE [UserID] = @UserID FOR XML PATH(''), TYPE ) return @xml end </code></pre> <p>To get all managers in an XML:</p> <pre><code>create proc GetAllManagers() as begin set nocount on; SELECT dbo.GetUser([UserID]) FROM Users WHERE [ManagerID] IS NULL FOR XML PATH(''), TYPE, root('Managers') end </code></pre> <p>Now to the problem. What if for each manager, I want all the users belonging to the manager? I would like my function to be able to call itself:</p> <pre><code>alter function GetUser(@UserID int, @IsIncludeChildren bit) returns XML as begin declare @xml XML SET @xml = ( SELECT [UserID] "User/@UserID" , [Name] "User/@Name" , (SELECT dbo.GetUser([UserID], 0)) "User/Children" FROM Users WHERE [ManagerID] = @UserID AND @IsIncludeChildren = 1 FOR XML PATH(''), TYPE ) return @xml end </code></pre> <p>and calling this simply</p> <pre><code>alter proc GetAllManagers() as begin set nocount on; SELECT dbo.GetUser([UserID], 1) FROM Users WHERE [ManagerID] IS NULL FOR XML PATH(''), TYPE, root('Managers') end </code></pre> <p>But this is not possible because of the nesting limit. So workaround is (using the first function):</p> <pre><code>alter proc GetAllManagers() as begin set nocount on; SELECT dbo.GetUser([UserID]) , ( SELECT dbo.GetUser([UserID]) FROM Users WHERE [ManagerID] = [Users].[UserID] FOR XML PATH(''), TYPE ) "User/Children" FROM Users as [Users] WHERE [ManagerID] IS NULL FOR XML PATH(''), TYPE, root('Managers') end </code></pre> <p>This is not too bad, but if you have lots of other procedures returning user data, you will have to build the parent/child relationship in all procs, instead of in a single function!</p> <p>So there, Microsoft, fix it!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload