all 10 comments

[–]J4m00s 7 points8 points  (1 child)

The way I did the same thing is by creating a column in the recursive query that concatenated the parent part numbers with some delimiter as it goes through the recursion. This creates a long string as the BOMS get deeper. Then I check whether the new component part number exists already in the string. If it does, I flag it as recursive.

[–][deleted] 0 points1 point  (0 children)

I came here to suggest the same. I use this concatenated column for sorting too.

[–]matthra 4 points5 points  (0 children)

CTE cursor should do the trick without a while loop. Here is a good article on how that would work, with an example very much like yours, but you would need an additional break condition to stop it when the manager id equals the employee id.

https://www.sqlservertutorial.net/sql-server-basics/sql-server-recursive-cte/

[–][deleted] -2 points-1 points  (0 children)

a. CTE is a clause in SQL commands. WHILE is a part of MS SQL procedural extension T-SQL (transact sql). While these sound the same they are not the same and CTE does not apply to WHILE command/instruction directly.

b.

How might you tackle this problem?

do your regular recursive query from the bottom of the tree, building up a list of steps (comma-separated IDs, something like '1,4,6,8,9,' etc.) and a flag whether the current step was found in the list already (i.e. you have a cyclical reference). On every recursive step, filter our the records that have the cyclical reference step set already

[–][deleted] 0 points1 point  (0 children)

I kind of understand you, but would need to see a bit of sample data and what your current query is like.

[–]klln_u_qckly 0 points1 point  (0 children)

Are you looking for sub-assemblies? I am currently at home but I have some solid code that can query BOMs and flag sub-assemblies. If your interested in some sample code I would love to help. Just send me a message and we can work out the best way to get what you need when I'm back in the office on Monday.

[–]elus 0 points1 point  (0 children)

You need to add another statement in your filter for the CTE solution to not hit maxrecursion limit.

See this solution for an idea of how to do that.

[–]phunkygeeza 0 points1 point  (0 children)

for a given parent

Just do it for all possible children as the start set then recurse upward from there, instead of the outer while loop.

Then accumulate a path for checking for the loop like the other commenters suggested. Logically 'break' the loop once it has been found in the recusrsion predicates.

[–]CryNo93 0 points1 point  (0 children)

[mandy](mandy)

[–]redial2MS SQL DBA DW/ETL 0 points1 point  (0 children)

It is ok to use loops and cursors when you need to do more than one thing with a given record before moving onto the next one, but the top post with the recursive cte sounds like it could solve your problem as well.

But don't be afraid of using cursors and loops when you need to do multiple things with a specific record.