CTE recursion infinite loopInfinite loop CTE with OPTION (maxrecursion 0)Difference between CTE and SubQuery?When to use Common Table Expression (CTE)Syntax of for-loop in SQL ServerIs there a performance difference between CTE , Sub-Query, Temporary Table or Table Variable?SQL Server CTE and recursion exampleCTE with recursion - row_number() aggregatedRecursive CTE or While LoopRecursive CTE result is infiniteTo find infinite recursive loop in CTECTE recursive query loops
How to correctly set logical high level on PS/2 port?
How to have the "Restore Missing Files" function from Nautilus without installing Nautilus?
Received email from ISP saying one of my devices has malware
Why does the U.S. military maintain their own weather satellites?
Am I required to correct my opponent's assumptions about my morph creatures?
How can I improve my formal definitions?
What are the French equivalents of "blow away the cobwebs"?
Why are CEOs generally fired rather being demoted?
Could these polynomials be identified?
Could a simple hospital oxygen mask protect from aerosol poison?
How to solve this inequality , when there is a irrational power?
The 7-numbers crossword
How to run a command 1 out of N times in Bash
Understanding GFCI configuration in basement
Would someone mind just getting me started with my Russian homework?
Do universities maintain secret textbooks?
Is Chuck the Evil Sandwich Making Guy's head actually a sandwich?
How could reincarnation magic be limited to prevent overuse?
"Practice makes perfect" and "c'est en forgeant qu'on devient forgeron"
Is Borg adaptation only temporary?
D Scale Question
New coworker has strange workplace requirements - how should I deal with them?
Squares inside a square
Displaying Time in HH:MM Format
CTE recursion infinite loop
Infinite loop CTE with OPTION (maxrecursion 0)Difference between CTE and SubQuery?When to use Common Table Expression (CTE)Syntax of for-loop in SQL ServerIs there a performance difference between CTE , Sub-Query, Temporary Table or Table Variable?SQL Server CTE and recursion exampleCTE with recursion - row_number() aggregatedRecursive CTE or While LoopRecursive CTE result is infiniteTo find infinite recursive loop in CTECTE recursive query loops
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I'm working with a stored procedure and using a CTE in SQL Server and I'm trying to reach some data from a 2 tables, but when the execution goes to the CTE query it gets an infinite loop and never ends, is there a way to prevent that infinite loop?
This is the query that I create:
WITH tableName(Id, enddate, statusDte, closeId, shceDte, calcDte, closeEndDte, ParentId, LastClose, lasCloseDte, closeClass,addSe,twon,code)
AS
(
SELECT
tba.Id,
CASE WHEN tb.ParentId IS NOT NULL
THEN tb.Id
WHEN tb.statusDte IN (1,2,3)
THEN tb.calcDte ELSE tb.shceDte
END ForecastDueDate,
statusDte, closeId, shceDte, calcDte,
CASE WHEN tb.ParentId IS NULL
THEN closeEndDte ELSE NULL END, tb.ParentId, 0,
CASE WHEN tb.ParentId IS NOT NULL
THEN statusDte
WHEN tb.statusDte = 5
AND (tb.calcDte BETWEEN '1/1/2020 12:00:00 AM' AND '12/31/2020 11:59:59 PM'
OR tb.closeEndDte BETWEEN '1/1/2020 12:00:00 AM' AND '12/31/2020 11:59:59 PM')
THEN ams.GetPreviousNthFullAuditDate(tb.Id, tb.AuditID, 2) ELSE a.statusDate END as lastDate,
a.closeClass, tba.addSe,tba.town,tba.code
FROM
tableA tba
INNER JOIN
tableB tb ON tb.Id = tba.Id
WHERE
statusDte NOT IN (3,4) AND tba.IsAtve = 1
UNION ALL
SELECT
Id, enddate,
statusDte, statusDte, shceDte, calcDte, closeEndDte, ParentId,
0, lasCloseDte, closeClass,addSe,twon,code
FROM
tableName
WHERE
enddate BETWEEN enddate AND '12/31/2020 11:59:59 PM'
)
SELECT *
FROM tableName
OPTION (maxrecursion 0)
Expected results
Id enddate statusDte closeId shceDte calcDte closeEndDte parentId lastClose lastCloseDte closeClass addSe town code
----------- ----------------------- ------------- ----------- ----------------------- ----------------------- ----------------------- ----------------------- ----------- ----------------------- ----------- --------------------------------- ---------------------- --------------------------------------------------
133 2011-04-04 00:00:00.000 22 14453 NULL 2011-04-04 00:00:00.000 2099-12-31 00:00:00.000 NULL 0 NULL 1 4707 EXECUTIVE DRIVE '' SAN DIEGO 123
56 2018-12-07 13:00:00.000 22 52354 NULL 2018-12-07 13:00:00.000 2019-12-07 00:00:00.000 NULL 0 NULL 1 75 STATE ST FL 24 '' BOSTON 345
12 2021-02-05 17:00:00.000 22 75751 NULL 2021-02-05 17:00:00.000 NULL NULL 0 NULL 1 1450 FRAZEE RD STE 308 '' SAN DIEGO 678
334 2019-03-07 16:30:00.000 15 66707 2019-03-07 16:30:00.000 2019-03-23 21:00:00.000 NULL NULL 0 2019-03-07 16:30:00.000 1 42690 RIO NEDO, STE E '' TEMECULA 91011
33 2020-01-10 17:00:00.000 22 65568 NULL 2020-01-10 17:00:00.000 NULL NULL 0 2018-01-10 17:00:00.000 1 2518 UNICORNIO ST. '' CARLSBAD 136
55 2020-04-16 20:00:00.000 22 67812 NULL 2020-04-16 20:00:00.000 NULL NULL 0 2018-04-17 20:00:00.000 1 4534 OSPREY STREET '' SAN DIEGO 653
66 2020-02-21 17:00:00.000 22 75956 NULL 2020-02-21 17:00:00.000 NULL NULL 0 2019-02-21 17:00:00.000 1 3511 CAMINO DEL RIO S, STE 305 '' SAN DIEGO 0484
094 2021-02-20 21:00:00.000 22 75629 NULL 2021-02-20 21:00:00.000 NULL NULL 0 NULL 1 29349 EAGLE DR '' MURRIETA 345
sql sql-server tsql
add a comment |
I'm working with a stored procedure and using a CTE in SQL Server and I'm trying to reach some data from a 2 tables, but when the execution goes to the CTE query it gets an infinite loop and never ends, is there a way to prevent that infinite loop?
This is the query that I create:
WITH tableName(Id, enddate, statusDte, closeId, shceDte, calcDte, closeEndDte, ParentId, LastClose, lasCloseDte, closeClass,addSe,twon,code)
AS
(
SELECT
tba.Id,
CASE WHEN tb.ParentId IS NOT NULL
THEN tb.Id
WHEN tb.statusDte IN (1,2,3)
THEN tb.calcDte ELSE tb.shceDte
END ForecastDueDate,
statusDte, closeId, shceDte, calcDte,
CASE WHEN tb.ParentId IS NULL
THEN closeEndDte ELSE NULL END, tb.ParentId, 0,
CASE WHEN tb.ParentId IS NOT NULL
THEN statusDte
WHEN tb.statusDte = 5
AND (tb.calcDte BETWEEN '1/1/2020 12:00:00 AM' AND '12/31/2020 11:59:59 PM'
OR tb.closeEndDte BETWEEN '1/1/2020 12:00:00 AM' AND '12/31/2020 11:59:59 PM')
THEN ams.GetPreviousNthFullAuditDate(tb.Id, tb.AuditID, 2) ELSE a.statusDate END as lastDate,
a.closeClass, tba.addSe,tba.town,tba.code
FROM
tableA tba
INNER JOIN
tableB tb ON tb.Id = tba.Id
WHERE
statusDte NOT IN (3,4) AND tba.IsAtve = 1
UNION ALL
SELECT
Id, enddate,
statusDte, statusDte, shceDte, calcDte, closeEndDte, ParentId,
0, lasCloseDte, closeClass,addSe,twon,code
FROM
tableName
WHERE
enddate BETWEEN enddate AND '12/31/2020 11:59:59 PM'
)
SELECT *
FROM tableName
OPTION (maxrecursion 0)
Expected results
Id enddate statusDte closeId shceDte calcDte closeEndDte parentId lastClose lastCloseDte closeClass addSe town code
----------- ----------------------- ------------- ----------- ----------------------- ----------------------- ----------------------- ----------------------- ----------- ----------------------- ----------- --------------------------------- ---------------------- --------------------------------------------------
133 2011-04-04 00:00:00.000 22 14453 NULL 2011-04-04 00:00:00.000 2099-12-31 00:00:00.000 NULL 0 NULL 1 4707 EXECUTIVE DRIVE '' SAN DIEGO 123
56 2018-12-07 13:00:00.000 22 52354 NULL 2018-12-07 13:00:00.000 2019-12-07 00:00:00.000 NULL 0 NULL 1 75 STATE ST FL 24 '' BOSTON 345
12 2021-02-05 17:00:00.000 22 75751 NULL 2021-02-05 17:00:00.000 NULL NULL 0 NULL 1 1450 FRAZEE RD STE 308 '' SAN DIEGO 678
334 2019-03-07 16:30:00.000 15 66707 2019-03-07 16:30:00.000 2019-03-23 21:00:00.000 NULL NULL 0 2019-03-07 16:30:00.000 1 42690 RIO NEDO, STE E '' TEMECULA 91011
33 2020-01-10 17:00:00.000 22 65568 NULL 2020-01-10 17:00:00.000 NULL NULL 0 2018-01-10 17:00:00.000 1 2518 UNICORNIO ST. '' CARLSBAD 136
55 2020-04-16 20:00:00.000 22 67812 NULL 2020-04-16 20:00:00.000 NULL NULL 0 2018-04-17 20:00:00.000 1 4534 OSPREY STREET '' SAN DIEGO 653
66 2020-02-21 17:00:00.000 22 75956 NULL 2020-02-21 17:00:00.000 NULL NULL 0 2019-02-21 17:00:00.000 1 3511 CAMINO DEL RIO S, STE 305 '' SAN DIEGO 0484
094 2021-02-20 21:00:00.000 22 75629 NULL 2021-02-20 21:00:00.000 NULL NULL 0 NULL 1 29349 EAGLE DR '' MURRIETA 345
sql sql-server tsql
2
The recursive part should relate somehow to the anchor part.
– Alex Kudryashev
Mar 28 at 0:28
Sure @D-Shih I updated the question with the information
– GeekDev
Mar 28 at 0:32
1
This answer demonstrates one way to terminate recursion when a loop is detected. A handy debugging technique is to add a column to the anchor, e.g.0 as Depth
, and increment it in the recursive part of the query,tableName.Depth + 1
, then use it in the recursivewhere
clause to limit the recursion depth, e.g.where Depth <= 2 and ...
, and examine the results. You should be able to spot the problem, though it may require increasing the depth limit until the issue becomes clear.
– HABO
Mar 28 at 2:26
add a comment |
I'm working with a stored procedure and using a CTE in SQL Server and I'm trying to reach some data from a 2 tables, but when the execution goes to the CTE query it gets an infinite loop and never ends, is there a way to prevent that infinite loop?
This is the query that I create:
WITH tableName(Id, enddate, statusDte, closeId, shceDte, calcDte, closeEndDte, ParentId, LastClose, lasCloseDte, closeClass,addSe,twon,code)
AS
(
SELECT
tba.Id,
CASE WHEN tb.ParentId IS NOT NULL
THEN tb.Id
WHEN tb.statusDte IN (1,2,3)
THEN tb.calcDte ELSE tb.shceDte
END ForecastDueDate,
statusDte, closeId, shceDte, calcDte,
CASE WHEN tb.ParentId IS NULL
THEN closeEndDte ELSE NULL END, tb.ParentId, 0,
CASE WHEN tb.ParentId IS NOT NULL
THEN statusDte
WHEN tb.statusDte = 5
AND (tb.calcDte BETWEEN '1/1/2020 12:00:00 AM' AND '12/31/2020 11:59:59 PM'
OR tb.closeEndDte BETWEEN '1/1/2020 12:00:00 AM' AND '12/31/2020 11:59:59 PM')
THEN ams.GetPreviousNthFullAuditDate(tb.Id, tb.AuditID, 2) ELSE a.statusDate END as lastDate,
a.closeClass, tba.addSe,tba.town,tba.code
FROM
tableA tba
INNER JOIN
tableB tb ON tb.Id = tba.Id
WHERE
statusDte NOT IN (3,4) AND tba.IsAtve = 1
UNION ALL
SELECT
Id, enddate,
statusDte, statusDte, shceDte, calcDte, closeEndDte, ParentId,
0, lasCloseDte, closeClass,addSe,twon,code
FROM
tableName
WHERE
enddate BETWEEN enddate AND '12/31/2020 11:59:59 PM'
)
SELECT *
FROM tableName
OPTION (maxrecursion 0)
Expected results
Id enddate statusDte closeId shceDte calcDte closeEndDte parentId lastClose lastCloseDte closeClass addSe town code
----------- ----------------------- ------------- ----------- ----------------------- ----------------------- ----------------------- ----------------------- ----------- ----------------------- ----------- --------------------------------- ---------------------- --------------------------------------------------
133 2011-04-04 00:00:00.000 22 14453 NULL 2011-04-04 00:00:00.000 2099-12-31 00:00:00.000 NULL 0 NULL 1 4707 EXECUTIVE DRIVE '' SAN DIEGO 123
56 2018-12-07 13:00:00.000 22 52354 NULL 2018-12-07 13:00:00.000 2019-12-07 00:00:00.000 NULL 0 NULL 1 75 STATE ST FL 24 '' BOSTON 345
12 2021-02-05 17:00:00.000 22 75751 NULL 2021-02-05 17:00:00.000 NULL NULL 0 NULL 1 1450 FRAZEE RD STE 308 '' SAN DIEGO 678
334 2019-03-07 16:30:00.000 15 66707 2019-03-07 16:30:00.000 2019-03-23 21:00:00.000 NULL NULL 0 2019-03-07 16:30:00.000 1 42690 RIO NEDO, STE E '' TEMECULA 91011
33 2020-01-10 17:00:00.000 22 65568 NULL 2020-01-10 17:00:00.000 NULL NULL 0 2018-01-10 17:00:00.000 1 2518 UNICORNIO ST. '' CARLSBAD 136
55 2020-04-16 20:00:00.000 22 67812 NULL 2020-04-16 20:00:00.000 NULL NULL 0 2018-04-17 20:00:00.000 1 4534 OSPREY STREET '' SAN DIEGO 653
66 2020-02-21 17:00:00.000 22 75956 NULL 2020-02-21 17:00:00.000 NULL NULL 0 2019-02-21 17:00:00.000 1 3511 CAMINO DEL RIO S, STE 305 '' SAN DIEGO 0484
094 2021-02-20 21:00:00.000 22 75629 NULL 2021-02-20 21:00:00.000 NULL NULL 0 NULL 1 29349 EAGLE DR '' MURRIETA 345
sql sql-server tsql
I'm working with a stored procedure and using a CTE in SQL Server and I'm trying to reach some data from a 2 tables, but when the execution goes to the CTE query it gets an infinite loop and never ends, is there a way to prevent that infinite loop?
This is the query that I create:
WITH tableName(Id, enddate, statusDte, closeId, shceDte, calcDte, closeEndDte, ParentId, LastClose, lasCloseDte, closeClass,addSe,twon,code)
AS
(
SELECT
tba.Id,
CASE WHEN tb.ParentId IS NOT NULL
THEN tb.Id
WHEN tb.statusDte IN (1,2,3)
THEN tb.calcDte ELSE tb.shceDte
END ForecastDueDate,
statusDte, closeId, shceDte, calcDte,
CASE WHEN tb.ParentId IS NULL
THEN closeEndDte ELSE NULL END, tb.ParentId, 0,
CASE WHEN tb.ParentId IS NOT NULL
THEN statusDte
WHEN tb.statusDte = 5
AND (tb.calcDte BETWEEN '1/1/2020 12:00:00 AM' AND '12/31/2020 11:59:59 PM'
OR tb.closeEndDte BETWEEN '1/1/2020 12:00:00 AM' AND '12/31/2020 11:59:59 PM')
THEN ams.GetPreviousNthFullAuditDate(tb.Id, tb.AuditID, 2) ELSE a.statusDate END as lastDate,
a.closeClass, tba.addSe,tba.town,tba.code
FROM
tableA tba
INNER JOIN
tableB tb ON tb.Id = tba.Id
WHERE
statusDte NOT IN (3,4) AND tba.IsAtve = 1
UNION ALL
SELECT
Id, enddate,
statusDte, statusDte, shceDte, calcDte, closeEndDte, ParentId,
0, lasCloseDte, closeClass,addSe,twon,code
FROM
tableName
WHERE
enddate BETWEEN enddate AND '12/31/2020 11:59:59 PM'
)
SELECT *
FROM tableName
OPTION (maxrecursion 0)
Expected results
Id enddate statusDte closeId shceDte calcDte closeEndDte parentId lastClose lastCloseDte closeClass addSe town code
----------- ----------------------- ------------- ----------- ----------------------- ----------------------- ----------------------- ----------------------- ----------- ----------------------- ----------- --------------------------------- ---------------------- --------------------------------------------------
133 2011-04-04 00:00:00.000 22 14453 NULL 2011-04-04 00:00:00.000 2099-12-31 00:00:00.000 NULL 0 NULL 1 4707 EXECUTIVE DRIVE '' SAN DIEGO 123
56 2018-12-07 13:00:00.000 22 52354 NULL 2018-12-07 13:00:00.000 2019-12-07 00:00:00.000 NULL 0 NULL 1 75 STATE ST FL 24 '' BOSTON 345
12 2021-02-05 17:00:00.000 22 75751 NULL 2021-02-05 17:00:00.000 NULL NULL 0 NULL 1 1450 FRAZEE RD STE 308 '' SAN DIEGO 678
334 2019-03-07 16:30:00.000 15 66707 2019-03-07 16:30:00.000 2019-03-23 21:00:00.000 NULL NULL 0 2019-03-07 16:30:00.000 1 42690 RIO NEDO, STE E '' TEMECULA 91011
33 2020-01-10 17:00:00.000 22 65568 NULL 2020-01-10 17:00:00.000 NULL NULL 0 2018-01-10 17:00:00.000 1 2518 UNICORNIO ST. '' CARLSBAD 136
55 2020-04-16 20:00:00.000 22 67812 NULL 2020-04-16 20:00:00.000 NULL NULL 0 2018-04-17 20:00:00.000 1 4534 OSPREY STREET '' SAN DIEGO 653
66 2020-02-21 17:00:00.000 22 75956 NULL 2020-02-21 17:00:00.000 NULL NULL 0 2019-02-21 17:00:00.000 1 3511 CAMINO DEL RIO S, STE 305 '' SAN DIEGO 0484
094 2021-02-20 21:00:00.000 22 75629 NULL 2021-02-20 21:00:00.000 NULL NULL 0 NULL 1 29349 EAGLE DR '' MURRIETA 345
sql sql-server tsql
sql sql-server tsql
edited Apr 27 at 20:38
marc_s
603k136 gold badges1152 silver badges1289 bronze badges
603k136 gold badges1152 silver badges1289 bronze badges
asked Mar 28 at 0:16
GeekDevGeekDev
7711 bronze badges
7711 bronze badges
2
The recursive part should relate somehow to the anchor part.
– Alex Kudryashev
Mar 28 at 0:28
Sure @D-Shih I updated the question with the information
– GeekDev
Mar 28 at 0:32
1
This answer demonstrates one way to terminate recursion when a loop is detected. A handy debugging technique is to add a column to the anchor, e.g.0 as Depth
, and increment it in the recursive part of the query,tableName.Depth + 1
, then use it in the recursivewhere
clause to limit the recursion depth, e.g.where Depth <= 2 and ...
, and examine the results. You should be able to spot the problem, though it may require increasing the depth limit until the issue becomes clear.
– HABO
Mar 28 at 2:26
add a comment |
2
The recursive part should relate somehow to the anchor part.
– Alex Kudryashev
Mar 28 at 0:28
Sure @D-Shih I updated the question with the information
– GeekDev
Mar 28 at 0:32
1
This answer demonstrates one way to terminate recursion when a loop is detected. A handy debugging technique is to add a column to the anchor, e.g.0 as Depth
, and increment it in the recursive part of the query,tableName.Depth + 1
, then use it in the recursivewhere
clause to limit the recursion depth, e.g.where Depth <= 2 and ...
, and examine the results. You should be able to spot the problem, though it may require increasing the depth limit until the issue becomes clear.
– HABO
Mar 28 at 2:26
2
2
The recursive part should relate somehow to the anchor part.
– Alex Kudryashev
Mar 28 at 0:28
The recursive part should relate somehow to the anchor part.
– Alex Kudryashev
Mar 28 at 0:28
Sure @D-Shih I updated the question with the information
– GeekDev
Mar 28 at 0:32
Sure @D-Shih I updated the question with the information
– GeekDev
Mar 28 at 0:32
1
1
This answer demonstrates one way to terminate recursion when a loop is detected. A handy debugging technique is to add a column to the anchor, e.g.
0 as Depth
, and increment it in the recursive part of the query, tableName.Depth + 1
, then use it in the recursive where
clause to limit the recursion depth, e.g. where Depth <= 2 and ...
, and examine the results. You should be able to spot the problem, though it may require increasing the depth limit until the issue becomes clear.– HABO
Mar 28 at 2:26
This answer demonstrates one way to terminate recursion when a loop is detected. A handy debugging technique is to add a column to the anchor, e.g.
0 as Depth
, and increment it in the recursive part of the query, tableName.Depth + 1
, then use it in the recursive where
clause to limit the recursion depth, e.g. where Depth <= 2 and ...
, and examine the results. You should be able to spot the problem, though it may require increasing the depth limit until the issue becomes clear.– HABO
Mar 28 at 2:26
add a comment |
2 Answers
2
active
oldest
votes
First, let's try to add some best practices. Qualify all your columns with the appropriate table alias. Just doing some of them is inconsistent and inconsistent style is difficult to read and prone to errors.
Next, you've (hopefully) dumbed down your actual query. Generic names like "tableA" hinder understanding.
Next - your first case expression seems highly suspicious. You have one branch returns tb.id and the others return what appears to be a date (or datetime). You can, unfortunately, cast an int to a datetime. Might not make any sense and it won't generate an error. So - does this make sense?
Next - you've made a common mistake with your datetime boundaries. Depending on your data you might never know this. But there is no reason to expect that and there is every reason to write your logic so that it avoids any possibility. Tibor discusses in great detail here. Shorter version - your upper boundary should always be an exclusive one to support all possible values of time for your datatype. 23:59:59 will ignore any time values with non-zero milliseconds. And use a literal format that is not dependent on language or connection settings.
Next, you add confusion. You named your columns in the cte declaration but your code also includes aliases for some (but not all - see, refer to the consistency comment) columns which differ significantly from the actual column name for the cte. The 2nd column for the cte is "enddate", the anchor query uses the alias "ForecastDueDate"
Next, you have this: tb.statusDte = 5. The name implies date; the literal implies something different. You have other columns that end in "Dte" that are obviously dates, but not this one? Danger, danger!
Next, you refer to columns "a.closeClass" and "a.statusDate". There is no table or alias named "a".
Lastly, you have:
WHERE enddate BETWEEN enddate AND '12/31/2020 11:59:59 PM'
Think about what you wrote. Is not enddate always between enddate and Dec 31 2010 (so long as enddate <= that value)? I think this is the source of your issue. You're not computing or adjusting anything from the anchor, so the recursed part just keeps selecting and selecting and selecting. There is no logic to end the recursion.
The next question is obviously "now to fix it". That is impossible to say without knowing your schema, what it represents, and your goal. The use of recursion here is not obvious.
thanks for the comment, yes the code is confusing, actually this is legacy code, I'm just trying to find a solution for this, I did a huge research about the cte and recursive query but nothing have help, but you are right this code does not have good practices at all. But thanks for the recomendations, I appreciate every comment or help! :)
– GeekDev
Mar 28 at 1:52
Something doesn't match. You said this is legacy code which implies you are porting/migrating it to something "new". And that implies you have added the recursion, otherwise it would also not work in the legacy system. Again - you need to understand exactly what this code does in the legacy system and what your goals are in migrating it (maybe "enhancing" is a better term).
– SMor
Mar 28 at 13:12
add a comment |
If the data is in a structure that the hierarchy between records is is a loop then recursion goes to infinite causing a problem in SQL. You will see the resources used by SQL process is increasing tremendously.
If you use MAXRECURSION with a different value than 0 (zero lets SQL to continue recursion without a limit) you will be able to limit the recursion.
With data that is looping or referencing each other you can this MAXRECURSION parameter
Thanks @Eralper! I tried with other values like 1,2 and 100 those values stop the infinite loop but in the app, I'm getting an error when that happens, because the query throws and alert message saying thatThe statement terminated. The maximum recursion 100 has been exhausted before statement completion.
So the dataset in the app does not get filled ans shows an error.
– GeekDev
Mar 28 at 15:50
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55388366%2fcte-recursion-infinite-loop%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
First, let's try to add some best practices. Qualify all your columns with the appropriate table alias. Just doing some of them is inconsistent and inconsistent style is difficult to read and prone to errors.
Next, you've (hopefully) dumbed down your actual query. Generic names like "tableA" hinder understanding.
Next - your first case expression seems highly suspicious. You have one branch returns tb.id and the others return what appears to be a date (or datetime). You can, unfortunately, cast an int to a datetime. Might not make any sense and it won't generate an error. So - does this make sense?
Next - you've made a common mistake with your datetime boundaries. Depending on your data you might never know this. But there is no reason to expect that and there is every reason to write your logic so that it avoids any possibility. Tibor discusses in great detail here. Shorter version - your upper boundary should always be an exclusive one to support all possible values of time for your datatype. 23:59:59 will ignore any time values with non-zero milliseconds. And use a literal format that is not dependent on language or connection settings.
Next, you add confusion. You named your columns in the cte declaration but your code also includes aliases for some (but not all - see, refer to the consistency comment) columns which differ significantly from the actual column name for the cte. The 2nd column for the cte is "enddate", the anchor query uses the alias "ForecastDueDate"
Next, you have this: tb.statusDte = 5. The name implies date; the literal implies something different. You have other columns that end in "Dte" that are obviously dates, but not this one? Danger, danger!
Next, you refer to columns "a.closeClass" and "a.statusDate". There is no table or alias named "a".
Lastly, you have:
WHERE enddate BETWEEN enddate AND '12/31/2020 11:59:59 PM'
Think about what you wrote. Is not enddate always between enddate and Dec 31 2010 (so long as enddate <= that value)? I think this is the source of your issue. You're not computing or adjusting anything from the anchor, so the recursed part just keeps selecting and selecting and selecting. There is no logic to end the recursion.
The next question is obviously "now to fix it". That is impossible to say without knowing your schema, what it represents, and your goal. The use of recursion here is not obvious.
thanks for the comment, yes the code is confusing, actually this is legacy code, I'm just trying to find a solution for this, I did a huge research about the cte and recursive query but nothing have help, but you are right this code does not have good practices at all. But thanks for the recomendations, I appreciate every comment or help! :)
– GeekDev
Mar 28 at 1:52
Something doesn't match. You said this is legacy code which implies you are porting/migrating it to something "new". And that implies you have added the recursion, otherwise it would also not work in the legacy system. Again - you need to understand exactly what this code does in the legacy system and what your goals are in migrating it (maybe "enhancing" is a better term).
– SMor
Mar 28 at 13:12
add a comment |
First, let's try to add some best practices. Qualify all your columns with the appropriate table alias. Just doing some of them is inconsistent and inconsistent style is difficult to read and prone to errors.
Next, you've (hopefully) dumbed down your actual query. Generic names like "tableA" hinder understanding.
Next - your first case expression seems highly suspicious. You have one branch returns tb.id and the others return what appears to be a date (or datetime). You can, unfortunately, cast an int to a datetime. Might not make any sense and it won't generate an error. So - does this make sense?
Next - you've made a common mistake with your datetime boundaries. Depending on your data you might never know this. But there is no reason to expect that and there is every reason to write your logic so that it avoids any possibility. Tibor discusses in great detail here. Shorter version - your upper boundary should always be an exclusive one to support all possible values of time for your datatype. 23:59:59 will ignore any time values with non-zero milliseconds. And use a literal format that is not dependent on language or connection settings.
Next, you add confusion. You named your columns in the cte declaration but your code also includes aliases for some (but not all - see, refer to the consistency comment) columns which differ significantly from the actual column name for the cte. The 2nd column for the cte is "enddate", the anchor query uses the alias "ForecastDueDate"
Next, you have this: tb.statusDte = 5. The name implies date; the literal implies something different. You have other columns that end in "Dte" that are obviously dates, but not this one? Danger, danger!
Next, you refer to columns "a.closeClass" and "a.statusDate". There is no table or alias named "a".
Lastly, you have:
WHERE enddate BETWEEN enddate AND '12/31/2020 11:59:59 PM'
Think about what you wrote. Is not enddate always between enddate and Dec 31 2010 (so long as enddate <= that value)? I think this is the source of your issue. You're not computing or adjusting anything from the anchor, so the recursed part just keeps selecting and selecting and selecting. There is no logic to end the recursion.
The next question is obviously "now to fix it". That is impossible to say without knowing your schema, what it represents, and your goal. The use of recursion here is not obvious.
thanks for the comment, yes the code is confusing, actually this is legacy code, I'm just trying to find a solution for this, I did a huge research about the cte and recursive query but nothing have help, but you are right this code does not have good practices at all. But thanks for the recomendations, I appreciate every comment or help! :)
– GeekDev
Mar 28 at 1:52
Something doesn't match. You said this is legacy code which implies you are porting/migrating it to something "new". And that implies you have added the recursion, otherwise it would also not work in the legacy system. Again - you need to understand exactly what this code does in the legacy system and what your goals are in migrating it (maybe "enhancing" is a better term).
– SMor
Mar 28 at 13:12
add a comment |
First, let's try to add some best practices. Qualify all your columns with the appropriate table alias. Just doing some of them is inconsistent and inconsistent style is difficult to read and prone to errors.
Next, you've (hopefully) dumbed down your actual query. Generic names like "tableA" hinder understanding.
Next - your first case expression seems highly suspicious. You have one branch returns tb.id and the others return what appears to be a date (or datetime). You can, unfortunately, cast an int to a datetime. Might not make any sense and it won't generate an error. So - does this make sense?
Next - you've made a common mistake with your datetime boundaries. Depending on your data you might never know this. But there is no reason to expect that and there is every reason to write your logic so that it avoids any possibility. Tibor discusses in great detail here. Shorter version - your upper boundary should always be an exclusive one to support all possible values of time for your datatype. 23:59:59 will ignore any time values with non-zero milliseconds. And use a literal format that is not dependent on language or connection settings.
Next, you add confusion. You named your columns in the cte declaration but your code also includes aliases for some (but not all - see, refer to the consistency comment) columns which differ significantly from the actual column name for the cte. The 2nd column for the cte is "enddate", the anchor query uses the alias "ForecastDueDate"
Next, you have this: tb.statusDte = 5. The name implies date; the literal implies something different. You have other columns that end in "Dte" that are obviously dates, but not this one? Danger, danger!
Next, you refer to columns "a.closeClass" and "a.statusDate". There is no table or alias named "a".
Lastly, you have:
WHERE enddate BETWEEN enddate AND '12/31/2020 11:59:59 PM'
Think about what you wrote. Is not enddate always between enddate and Dec 31 2010 (so long as enddate <= that value)? I think this is the source of your issue. You're not computing or adjusting anything from the anchor, so the recursed part just keeps selecting and selecting and selecting. There is no logic to end the recursion.
The next question is obviously "now to fix it". That is impossible to say without knowing your schema, what it represents, and your goal. The use of recursion here is not obvious.
First, let's try to add some best practices. Qualify all your columns with the appropriate table alias. Just doing some of them is inconsistent and inconsistent style is difficult to read and prone to errors.
Next, you've (hopefully) dumbed down your actual query. Generic names like "tableA" hinder understanding.
Next - your first case expression seems highly suspicious. You have one branch returns tb.id and the others return what appears to be a date (or datetime). You can, unfortunately, cast an int to a datetime. Might not make any sense and it won't generate an error. So - does this make sense?
Next - you've made a common mistake with your datetime boundaries. Depending on your data you might never know this. But there is no reason to expect that and there is every reason to write your logic so that it avoids any possibility. Tibor discusses in great detail here. Shorter version - your upper boundary should always be an exclusive one to support all possible values of time for your datatype. 23:59:59 will ignore any time values with non-zero milliseconds. And use a literal format that is not dependent on language or connection settings.
Next, you add confusion. You named your columns in the cte declaration but your code also includes aliases for some (but not all - see, refer to the consistency comment) columns which differ significantly from the actual column name for the cte. The 2nd column for the cte is "enddate", the anchor query uses the alias "ForecastDueDate"
Next, you have this: tb.statusDte = 5. The name implies date; the literal implies something different. You have other columns that end in "Dte" that are obviously dates, but not this one? Danger, danger!
Next, you refer to columns "a.closeClass" and "a.statusDate". There is no table or alias named "a".
Lastly, you have:
WHERE enddate BETWEEN enddate AND '12/31/2020 11:59:59 PM'
Think about what you wrote. Is not enddate always between enddate and Dec 31 2010 (so long as enddate <= that value)? I think this is the source of your issue. You're not computing or adjusting anything from the anchor, so the recursed part just keeps selecting and selecting and selecting. There is no logic to end the recursion.
The next question is obviously "now to fix it". That is impossible to say without knowing your schema, what it represents, and your goal. The use of recursion here is not obvious.
answered Mar 28 at 1:17
SMorSMor
1,6542 gold badges6 silver badges9 bronze badges
1,6542 gold badges6 silver badges9 bronze badges
thanks for the comment, yes the code is confusing, actually this is legacy code, I'm just trying to find a solution for this, I did a huge research about the cte and recursive query but nothing have help, but you are right this code does not have good practices at all. But thanks for the recomendations, I appreciate every comment or help! :)
– GeekDev
Mar 28 at 1:52
Something doesn't match. You said this is legacy code which implies you are porting/migrating it to something "new". And that implies you have added the recursion, otherwise it would also not work in the legacy system. Again - you need to understand exactly what this code does in the legacy system and what your goals are in migrating it (maybe "enhancing" is a better term).
– SMor
Mar 28 at 13:12
add a comment |
thanks for the comment, yes the code is confusing, actually this is legacy code, I'm just trying to find a solution for this, I did a huge research about the cte and recursive query but nothing have help, but you are right this code does not have good practices at all. But thanks for the recomendations, I appreciate every comment or help! :)
– GeekDev
Mar 28 at 1:52
Something doesn't match. You said this is legacy code which implies you are porting/migrating it to something "new". And that implies you have added the recursion, otherwise it would also not work in the legacy system. Again - you need to understand exactly what this code does in the legacy system and what your goals are in migrating it (maybe "enhancing" is a better term).
– SMor
Mar 28 at 13:12
thanks for the comment, yes the code is confusing, actually this is legacy code, I'm just trying to find a solution for this, I did a huge research about the cte and recursive query but nothing have help, but you are right this code does not have good practices at all. But thanks for the recomendations, I appreciate every comment or help! :)
– GeekDev
Mar 28 at 1:52
thanks for the comment, yes the code is confusing, actually this is legacy code, I'm just trying to find a solution for this, I did a huge research about the cte and recursive query but nothing have help, but you are right this code does not have good practices at all. But thanks for the recomendations, I appreciate every comment or help! :)
– GeekDev
Mar 28 at 1:52
Something doesn't match. You said this is legacy code which implies you are porting/migrating it to something "new". And that implies you have added the recursion, otherwise it would also not work in the legacy system. Again - you need to understand exactly what this code does in the legacy system and what your goals are in migrating it (maybe "enhancing" is a better term).
– SMor
Mar 28 at 13:12
Something doesn't match. You said this is legacy code which implies you are porting/migrating it to something "new". And that implies you have added the recursion, otherwise it would also not work in the legacy system. Again - you need to understand exactly what this code does in the legacy system and what your goals are in migrating it (maybe "enhancing" is a better term).
– SMor
Mar 28 at 13:12
add a comment |
If the data is in a structure that the hierarchy between records is is a loop then recursion goes to infinite causing a problem in SQL. You will see the resources used by SQL process is increasing tremendously.
If you use MAXRECURSION with a different value than 0 (zero lets SQL to continue recursion without a limit) you will be able to limit the recursion.
With data that is looping or referencing each other you can this MAXRECURSION parameter
Thanks @Eralper! I tried with other values like 1,2 and 100 those values stop the infinite loop but in the app, I'm getting an error when that happens, because the query throws and alert message saying thatThe statement terminated. The maximum recursion 100 has been exhausted before statement completion.
So the dataset in the app does not get filled ans shows an error.
– GeekDev
Mar 28 at 15:50
add a comment |
If the data is in a structure that the hierarchy between records is is a loop then recursion goes to infinite causing a problem in SQL. You will see the resources used by SQL process is increasing tremendously.
If you use MAXRECURSION with a different value than 0 (zero lets SQL to continue recursion without a limit) you will be able to limit the recursion.
With data that is looping or referencing each other you can this MAXRECURSION parameter
Thanks @Eralper! I tried with other values like 1,2 and 100 those values stop the infinite loop but in the app, I'm getting an error when that happens, because the query throws and alert message saying thatThe statement terminated. The maximum recursion 100 has been exhausted before statement completion.
So the dataset in the app does not get filled ans shows an error.
– GeekDev
Mar 28 at 15:50
add a comment |
If the data is in a structure that the hierarchy between records is is a loop then recursion goes to infinite causing a problem in SQL. You will see the resources used by SQL process is increasing tremendously.
If you use MAXRECURSION with a different value than 0 (zero lets SQL to continue recursion without a limit) you will be able to limit the recursion.
With data that is looping or referencing each other you can this MAXRECURSION parameter
If the data is in a structure that the hierarchy between records is is a loop then recursion goes to infinite causing a problem in SQL. You will see the resources used by SQL process is increasing tremendously.
If you use MAXRECURSION with a different value than 0 (zero lets SQL to continue recursion without a limit) you will be able to limit the recursion.
With data that is looping or referencing each other you can this MAXRECURSION parameter
answered Mar 28 at 5:47
EralperEralper
5,4521 gold badge14 silver badges23 bronze badges
5,4521 gold badge14 silver badges23 bronze badges
Thanks @Eralper! I tried with other values like 1,2 and 100 those values stop the infinite loop but in the app, I'm getting an error when that happens, because the query throws and alert message saying thatThe statement terminated. The maximum recursion 100 has been exhausted before statement completion.
So the dataset in the app does not get filled ans shows an error.
– GeekDev
Mar 28 at 15:50
add a comment |
Thanks @Eralper! I tried with other values like 1,2 and 100 those values stop the infinite loop but in the app, I'm getting an error when that happens, because the query throws and alert message saying thatThe statement terminated. The maximum recursion 100 has been exhausted before statement completion.
So the dataset in the app does not get filled ans shows an error.
– GeekDev
Mar 28 at 15:50
Thanks @Eralper! I tried with other values like 1,2 and 100 those values stop the infinite loop but in the app, I'm getting an error when that happens, because the query throws and alert message saying that
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
So the dataset in the app does not get filled ans shows an error.– GeekDev
Mar 28 at 15:50
Thanks @Eralper! I tried with other values like 1,2 and 100 those values stop the infinite loop but in the app, I'm getting an error when that happens, because the query throws and alert message saying that
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
So the dataset in the app does not get filled ans shows an error.– GeekDev
Mar 28 at 15:50
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55388366%2fcte-recursion-infinite-loop%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
The recursive part should relate somehow to the anchor part.
– Alex Kudryashev
Mar 28 at 0:28
Sure @D-Shih I updated the question with the information
– GeekDev
Mar 28 at 0:32
1
This answer demonstrates one way to terminate recursion when a loop is detected. A handy debugging technique is to add a column to the anchor, e.g.
0 as Depth
, and increment it in the recursive part of the query,tableName.Depth + 1
, then use it in the recursivewhere
clause to limit the recursion depth, e.g.where Depth <= 2 and ...
, and examine the results. You should be able to spot the problem, though it may require increasing the depth limit until the issue becomes clear.– HABO
Mar 28 at 2:26