473,779 Members | 2,072 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

order of recursion in stored procedure

Dan
I've encountered some strange behavior in a recursive procedure I'm
writing for a bill of materials. First let me ask directly if what I
think is happening is even possible:

It seems like the procedure is not following the recursion in serial
order, but in parallel. In other words, after one instance of the
procedure calls itself, it continues executing lines below the
recursion before the recursion is done. Is that possible? I looked
for SQL Server Options that might deal with recursion or threading but
I couldn't find anything.

Now let me explain what's happening in terms of the BoM. All the rows
I expect are returned, but not in the correct order. Let's assume the
following tree:

1
|-2
| |-5
| | |-7
| | \-8
| \-6
| \-9
|-3
| |-10
| |-11
| | |-13
| | \-14
| | |-15
| | |-16
| | \-17
| \-12
| \-18
| \-19
| \-20
| |-21
| \-22
\-4
\-23
|-24
\-25
\-26

This is stored in table P using MemberID and ParentID fields. For
example,

MemberID ParentID
-------- --------
1 NULL
2 1
3 1
4 1
5 2
6 2
(etc...)

Based on how I wrote the recursion (I will provide the procedure
below), I would expect output when starting from MemberID of 1 to look
like this:

MemberID Depth Sort
-------- ----- ----
2 1 1
5 2 2
7 3 3
8 3 4
6 2 5
9 3 6
(etc... basically, the line order of the graphical tree above, or a
counter-clockwise traverse around the tree)

Instead, I get this (I'll provide the whole thing because I don't see
a pattern):

MemberID Depth Sort
-------- ----- ----
2 1 1
5 2 2
3 1 2
10 2 3
7 3 3
4 1 3
6 2 3
9 3 4
23 2 4
8 3 4
11 2 4
13 3 5
12 2 5
24 3 5
25 3 6
18 3 6
14 3 6
15 4 7
19 4 7
26 4 7
20 5 8
16 4 8
17 4 9
21 6 9
22 6 10

Call me crazy, but it looks like my tree was parsed in the same order
that a set of dominos arranged in the same shape would topple. The
only way I could see that happening is if the recursion is non-linear,
allowing both children and siblings to be parsed simultaneously. It
would also explain why my sort counter didn't increment properly, but
the depth counter is always correct.

Now here are the procedures. There's also a Qty column, since this is
a BoM after all, but I didn't need to mention it for my illustration
of the problem above.

CREATE PROC makebom @root bigint
--
-- This would be called by the client to find all the parts and
quantities
-- under a specific part (@root)
--
AS
SET NOCOUNT ON
CREATE TABLE #result (MemberID bigint, Qty bigint, Depth bigint, sort
bigint)
EXEC bomrecurse @root, 1, 0
SET NOCOUNT OFF
SELECT MemberID, Qty, Depth, sort FROM #result ORDER BY sort
GO

CREATE PROC bomrecurse @root bigint, @depthcounter bigint,
@sortcounter bigint
--
-- This is the recursive procedure, called once by makebom, but
recalling
-- itself until the whole tree is parsed, filling the #result table
--
AS

DECLARE @memberid bigint, @qty bigint, @nextdepth bigint

DECLARE children_cursor CURSOR LOCAL FOR
SELECT MemberID, Qty FROM P
WHERE ParentID = @root
ORDER BY MemberID

OPEN children_cursor

FETCH NEXT FROM children_cursor
INTO @memberid, @qty

WHILE @@FETCH_STATUS = 0
BEGIN
SET @sortcounter = @sortcounter + 1
INSERT INTO #result VALUES (@memberid, @qty, @depthcounter,
@sortcounter)

SET @nextdepth = @depthcounter + 1
EXEC bomrecurse @memberid, @nextdepth, @sortcounter

FETCH NEXT FROM children_cursor
INTO @memberid, @qty
END

CLOSE children_cursor
DEALLOCATE children_cursor

GO
I'm surprised this even worked as well as it did because I'm a newbie
when it comes to stored procedures and I put this together from
examples I found around this group, online and in the T-SQL Help. So
feel free to comment on other aspects of my code or approach, but I'm
most interested in understanding the behavior of this recursion.
Jul 20 '05 #1
4 2580
Dan (th*******@gmai l.com) writes:
I've encountered some strange behavior in a recursive procedure I'm
writing for a bill of materials. First let me ask directly if what I
think is happening is even possible:

It seems like the procedure is not following the recursion in serial
order, but in parallel. In other words, after one instance of the
procedure calls itself, it continues executing lines below the
recursion before the recursion is done. Is that possible?
No, it is not.

You included the code to your procedures, but unfortunately you did
not include any CREATE TABLE statements or INSERT statements with
sample data. (Thus, I would have to type those myself, and I am lazy.)

Then again, there is something in your code that I don't understand:
CREATE PROC bomrecurse @root bigint, @depthcounter bigint,
@sortcounter bigint
...
DECLARE children_cursor CURSOR LOCAL FOR
SELECT MemberID, Qty FROM P
WHERE ParentID = @root
ORDER BY MemberID

OPEN children_cursor

FETCH NEXT FROM children_cursor
INTO @memberid, @qty

WHILE @@FETCH_STATUS = 0
BEGIN
SET @sortcounter = @sortcounter + 1
INSERT INTO #result VALUES (@memberid, @qty, @depthcounter,
@sortcounter)

SET @nextdepth = @depthcounter + 1
EXEC bomrecurse @memberid, @nextdepth, @sortcounter


Say that you have a simple tree of two nodes A and B, which both have four
children that are leaf nodes. When you start with A, @sortcounter is 0,
which you increment and insert 1 into the table. Then you recurse, for
the four children you insert the values 2, 3, 4 and 5. Then you come back,
and for the B you insert 2 into #result and then 3, 4, 5 and 6 into
#result. It may be the late hour over here, but I don't really see what
the purpose might be with this. If I guess, shouldn't you make @sortcounter
an OUTPUT parameter, so that you get the value back from the recursion?

(Note that you need to specify OUTPUT both in CREATE PROCEDURE and in the
EXEC statement.)
--
Erland Sommarskog, SQL Server MVP, es****@sommarsk og.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #2
Dan
On Mon, 9 Aug 2004 22:31:52 +0000 (UTC), Erland Sommarskog
<es****@sommars kog.se> wrote:
You included the code to your procedures, but unfortunately you did
not include any CREATE TABLE statements or INSERT statements with
sample data. (Thus, I would have to type those myself, and I am lazy.)
I would have if I knew how to generate the INSERT with sample data.
(Have the server generate it, I mean. I'm not typing it all myself
either!) I could do the CREATE TABLE statement but without the data
that's rather useless.
CREATE PROC bomrecurse @root bigint, @depthcounter bigint,
@sortcounter bigint
...
DECLARE children_cursor CURSOR LOCAL FOR
SELECT MemberID, Qty FROM P
WHERE ParentID = @root
ORDER BY MemberID

OPEN children_cursor

FETCH NEXT FROM children_cursor
INTO @memberid, @qty

WHILE @@FETCH_STATUS = 0
BEGIN
SET @sortcounter = @sortcounter + 1
INSERT INTO #result VALUES (@memberid, @qty, @depthcounter,
@sortcounter)

SET @nextdepth = @depthcounter + 1
EXEC bomrecurse @memberid, @nextdepth, @sortcounter


Say that you have a simple tree of two nodes A and B, which both have four
children that are leaf nodes. When you start with A, @sortcounter is 0,
which you increment and insert 1 into the table. Then you recurse, for
the four children you insert the values 2, 3, 4 and 5. Then you come back,
and for the B you insert 2 into #result and then 3, 4, 5 and 6 into
#result. It may be the late hour over here, but I don't really see what
the purpose might be with this.


Good eye. My intent was to simply give each row a "sort" value equal
to its row number in the result table. This is unnecessary if the end
client doesn't REsort it, but I didn't wan to count on that. You're
right - it won't work as I wrote it.
If I guess, shouldn't you make @sortcounter
an OUTPUT parameter, so that you get the value back from the recursion?

(Note that you need to specify OUTPUT both in CREATE PROCEDURE and in the
EXEC statement.)


That sounds like the way to do it - thanks.

Still no idea why the tree is being parsed like dominos though?
Jul 20 '05 #3
Dan
Dan <th*******@goog le.com> wrote in message news:<s3******* *************** **********@4ax. com>...
On Mon, 9 Aug 2004 22:31:52 +0000 (UTC), Erland Sommarskog
<es****@sommars kog.se> wrote:

If I guess, shouldn't you make @sortcounter
an OUTPUT parameter, so that you get the value back from the recursion?

(Note that you need to specify OUTPUT both in CREATE PROCEDURE and in the
EXEC statement.)


That sounds like the way to do it - thanks.

Still no idea why the tree is being parsed like dominos though?


Nevermind. I suddenly see the light. :) The loss of @sortcounter's
value when it stepped out of recursion was what caused not only the
duplicate values but subsequently the apparent domino-order parsing.
I would've seen this sooner if I hadn't sorted by @sortcounter's
column.

Making the @sortcounter an OUTPUT parameter solved everything.
Thanks!
Jul 20 '05 #4
Dan (th*******@goog le.com) writes:
I would have if I knew how to generate the INSERT with sample data.
(Have the server generate it, I mean. I'm not typing it all myself
either!)


This is moot point now, since you were able to resolve your problem, but
permit me to point out that for this case an example of 10 rows should
probably do, which should not be a problem for you type if you were
interesting in getting assistance with the problem.

If you would need to script out many rows for some reason, there is
no builtin tool for this in SQL Server, however SQL Server MVP Vyas
Kondreddi has a nifty utility for this on his site,
http://vyaskn.tripod.com/code.htm#inserts
--
Erland Sommarskog, SQL Server MVP, es****@sommarsk og.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

699
34238
by: mike420 | last post by:
I think everyone who used Python will agree that its syntax is the best thing going for it. It is very readable and easy for everyone to learn. But, Python does not a have very good macro capabilities, unfortunately. I'd like to know if it may be possible to add a powerful macro system to Python, while keeping its amazing syntax, and if it could be possible to add Pythonistic syntax to Lisp or Scheme, while keeping all of the...
4
3091
by: Rick Snagglehimer | last post by:
I keep getting an error from the following SP snippet "Line 11: Incorrect syntax near 'BY'." It runs fine without the ORDER BY clause. >>>>>>>>>>>>>>> WHERE .clientID = .userID
3
22146
by: dinesh prasad | last post by:
I'm trying to use a servlet to process a form, then send that data to an SQL server stored procedure. I'm using the WebLogic 8 App. server. I am able to retrieve database information, so I know my application server can talk to the database. I've determined the failure occurs when the the following statement is executed: cstmt.execute(); (due to the failure of println statements placed afterwards). I get the following error after trying to...
7
10240
by: Alex Vorobiev | last post by:
hi there, i am using sql server 7. below is the stored procedure that is giving me grief. its purpose it two-fold, depending on how it is called: either to return a pageset (based on page number and page size), or to return IDs of previous and next records (based on current record id). the problem is, that the order in which records are inserted into the temp table is inconsistent, even though the calling statement and the order by is...
1
3072
by: Icarus | last post by:
Is it possible to have to ORDER BY statements in the same stored procedure? I am trying to use the same stored procedure for two different pages but the data returned needs to sorted DESC on one page and ASC on another. Below is my SP: CREATE procedure sp_getLeads @p_SortType int, @p_PropID int
2
1700
by: Irishmaninusa | last post by:
Hello Everyone, I am populating a dropdown control from a database where the data is datetime values. In my stored procedure I am ordering them by where the most recent is at the top and the earliest is the last. So the following is displayed in SQL Query Analyzer 7/28/2004 7/1/2004 6/302004
104
10901
by: Beowulf | last post by:
I have the view below and if I use vwRouteReference as the rowsource for a combo box in an MS Access form or run "SELECT * FROM vwRouteReference" in SQL Query Analyzer, the rows don't come through sorted by Numb. Everything I've read on the web suggests that including the TOP directive should enable ORDERY BY in views. Does someone have an idea why the sorting is not working correctly for this particular view? thanks. CREATE VIEW...
0
2827
balabaster
by: balabaster | last post by:
Hi, I have a couple of tables: Units( Unit_PKey Int Identity(1,1) Primary Key, Unit_Name nvarchar(8), Unit_Description nvarchar(32) )
35
4741
by: Muzammil | last post by:
int harmonic(int n) { if (n=1) { return 1; } else { return harmonic(n-1)+1/n; } } can any help me ??
0
9636
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9474
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10306
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10139
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10075
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9931
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6727
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5504
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2869
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.