stegro
19th August 2013, 23:18
Hey there,

I already searched this site and read all about possible recursion solutions, best would fit this one (copied from the Crossing recursion thread)

I still get the "recursion not yet implemented" error, could someone help me with it?

I just cannot see why it wont work?!

Thank you.


"|****************************** function section ******************************

functions:

function read.main.table()
{
level.recursion = level.recursion + 1
sql.x=sql.parse("select tipcf310.* " &
"from tipcf310 " &
"where tipcf310._index1 = {:1}")
sql.where.bind(sql.x,1,mitm.f)
sql(level.recursion)=sql.x
sql.exec(sql.x)
while (sql.fetch(sql.x) = 0)
rprt_send()
mitm.f = tipcf310.sitm
mitm.w = tipcf310.mitm
read.main.table()
endwhile
sql.close(sql.x)
level.recursion = level.recursion - 1
if level.recursion <> 0 then
sql.x=sql(level.recursion)
endif
}"

bhushanchanda
20th August 2013, 06:59
Hi,

I have not put my hands in recursions as I use aliases. Anyway, I am not sure if you have gone through this, but here's a thread which might solve your issue.

Thread (http://www.baanboard.com/baanboard/showthread.php?t=22850&highlight=recursion)

Some where I found a statement saying, you need to declare the variables sql.x , level.recursion as static.

Go through the thread carefully and you will get it.

Other threads:-

Thread 1 (http://www.baanboard.com/node/1739)
Thread 2 (http://www.baanboard.com/baanboard/showthread.php?t=54466)
Thread 3 (http://www.baanboard.com/baanboard/showthread.php?t=22972)

ulrich.fuchs
20th August 2013, 08:10
Stegro,

in that case, sql.x will be a global variable, I guess. So your code will most certainly produce a memory leak: you will only close the last of your queries executed, all others stay open. It might be that during the sql parsing there are some local variables defined internally that eventually lead to that code to be not compilable, but you should be happy it isn't.

Please use iterative programming when doing BOM explosion (using a stack), recursion is a hack that should be avoided as much as possible.


table ttibom010 | Bill of Material

extern domain tcitem toplvl.item fixed
extern domain tcitem kit.item fixed


#define MAXSTACK 2000
long stack.pointer
domain tcitem stack.item (MAXSTACK) | Current Item
domain tcpono stack.pono (MAXSTACK) | Current Bom line
domain tcmcs.long stack.level (MAXSTACK) | Level of current line



|****************************** program section ********************************


|****************************** group section **********************************

group.1:
init.group:
get.screen.defaults()

functions:
function extern long do.process ()
{
if choice.report (spool.report) then
if rprt_open() then
read.main.table()
rprt_close()
endif
endif
return (0)
}

function void read.main.table () {
set.mem (stack.item, "")
set.mem (stack.pono, 0)
stack.pointer = 1
stack.item (1,1) = toplvl.item
stack.pono (1) = 0
stack.level(1) = 0

stack.level(1) = 1
while stack.pointer > 0

if explode.current.stack.position() then
dal.set.error.message ("@Serious Error during BOM explosion. Aborting.")
show.dal.messages ()
break
endif

endwhile
}


function long explode.current.stack.position()
{
domain tcitem l.item
domain tcpono l.pono
domain tcitem current.item

l.item = stackitem (1,stack.pointer)
l.pono = stack.pono (stack.pointer)

select tibom010.*
from tibom010
where tibom010._index1 = {:l.item}
and tibom010.pono > :l.pono
order by tibom010._index1
as set with 1 rows
selectdo
current.item = tibom010.sitm

| Position als bearbeitet merken:
stack.pono (stack.pointer) = tibom010.pono

| Nächste Position zur Auflösung auf den Stack schlichen auf den Stack schlichten
if stack.pointer < MAXSTACK then
stack.pointer = stack.pointer + 1
else
dal.set.error.message ("@Stack-Überlauf: Mehr als 2000 zwischenzuspeichernde Materialpositionen!")
return (DALHOOKERROR)
endif


stack.item (1,stack.pointer) = current.item
stack.pono (stack.pointer) = 0
stack.level (stack.pointer) = stack.level (stack.pointer-1) +1

selectempty
stack.pointer = stack.pointer - 1
endselect


return (0)
}

stegro
20th August 2013, 12:28
Hello, thanks for your help!
I will try Ulrich Fuchs' way. I certainly will run in a performance problem, I do not need a memory problem in addition....
I will post again as soon as I have either another question or a result....

vamsi_gujjula
20th August 2013, 14:58
long recu.level,curr.sql.id, sql.id(199) |#602764-001.en

------------------------------------------------------
function check.component.present.in.bom() |#602764-001.sn
{
|*Function to check whether component present in BOM and get BOM net qty.
recu.level = recu.level + 1

curr.sql.id = sql.parse("select tibom010.* "&
"from tibom010 "&
"where tibom010._index1 = :1 "&
"and tibom010._compnr = :2 "&
"and ((tibom010.exdt = 0 and tibom010.indt <= :3 ) "& |#603112-001.n
"or (tibom010.exdt >= :3 and tibom010.indt <= :3))") |#603112-001.n


ret=sql.where.bind(curr.sql.id,1, g.mitm)
ret=sql.where.bind(curr.sql.id,2, tccom000.ncmp)
ret=sql.where.bind(curr.sql.id,3, tisfc001.prdt)

sql.id(recu.level) = curr.sql.id
ret=sql.exec(curr.sql.id)

while (sql.fetch(curr.sql.id) = 0)
if not sitm.found then
if tibom010.sitm = ticst001.sitm then
g.mitm = ""
sitm.qana = tibom010.qana
sitm.found = true
break
else
g.mitm = tibom010.sitm
check.component.present.in.bom()
endif
endif
endwhile

sql.close(curr.sql.id)
recu.level = recu.level - 1
if recu.level <> 0 then
curr.sql.id = sql.id(recu.level)
endif
} |#602764-001.en

this is running code from one of our sessions.

regards,
vamsi.

sam291091
21st April 2016, 07:04
Hi vamsi,
I did same logic as you defined and it is working fine also but for some case i got fetal error stack overflow entries > 500. I also attach screen shot.

any solution for this?

Ajesh
21st April 2016, 09:11
Probably not all the sql queries are getting closed. Anyway whats the code?

sam291091
21st April 2016, 09:48
Hi Ajesh,
I am attaching screen shot of debug mode stack trace.

Ajesh
21st April 2016, 10:53
Hi Sam

I mean the code which you wrote for Recursion, the one including the dynamic SQLS.

sam291091
21st April 2016, 11:09
Hi Ajesh,

function check.component.present.in.bom()
{
recu.level = recu.level + 1

curr.sql.id = sql.parse("select tibom010.* "&
"from tibom010 "&
"where tibom010._index1 = :1 ")

ret = sql.where.bind(curr.sql.id,1,mitm)

sql.id(recu.level) = curr.sql.id
ret = sql.exec(curr.sql.id)

while (sql.fetch(curr.sql.id) = 0)
if check.if.manufac(tibom010.sitm) then
mitm = tibom010.sitm
ltrpd201.item = mitm
i.level = recu.level
get.qnty = tibom010.qana
insert.fkms.serialize.data.in.to.ltrpd201(tibom010.sitm,tibom010.mitm,get.qnty,i.level)
check.component.present.in.bom()
else
mitm = tibom010.sitm
ltrpd201.item = tibom010.sitm
i.level = recu.level
get.qnty = tibom010.qana
insert.fkms.serialize.data.in.to.ltrpd201(tibom010.sitm,tibom010.mitm,get.qnty,i.level)
check.component.present.in.bom()
endif

endwhile

sql.close(curr.sql.id)
recu.level = recu.level - 1
if recu.level <> 0 then
curr.sql.id = sql.id(recu.level)
endif


}

vamsi_gujjula
21st April 2016, 13:05
Bshell
maximum function stack depth is 500

I guess that has nothing to do with sqls but rather the no. of functional calls

I have seen the code .. i see you are using recursion for non manufacturing item's items as well any idea why ?? Probably you can optimize the code.. to reduce the no. of calls.. ??

Ajesh
21st April 2016, 13:47
Pl Try this. According to me, we need not use sql.parse in every recursion. Once done is enough. After all we are just changing the bind variable and not the query itself.

Also, i have introduced sql.break in the recursion, just before giving a recursive call to the function.


boolean first.time

first.time = true

function check.component.present.in.bom()
{



if first.time then
sql.id = sql.parse("select tibom010.* "&
"from tibom010 "&
"where tibom010._index1 = :1 ")
first.time = false
recu.level = 1
else
recu.level = recu.level + 1
endif
ret = sql.where.bind(sql.id,1,mitm)

ret = sql.exec(sql.id)
while (sql.fetch(sql.id) = 0)
if check.if.manufac(tibom010.sitm) then
mitm = tibom010.sitm
ltrpd201.item = mitm
i.level = recu.level
get.qnty = tibom010.qana
insert.fkms.serialize.data.in.to.ltrpd201(tibom010.sitm,tibom010.mitm,get.qnty,i.level)
sql.break(sql.id) |Introduced break |as we will be changing the bind variable next time
check.component.present.in.bom()
else
mitm = tibom010.sitm
ltrpd201.item = tibom010.sitm
i.level = recu.level
get.qnty = tibom010.qana
insert.fkms.serialize.data.in.to.ltrpd201(tibom010.sitm,tibom010.mitm,get.qnty,i.level)
sql.break(sql.id) |Introduced break as we will be |changing the bind variable next time
check.component.present.in.bom()
endif

endwhile
sql.break(sql.id)
sql.close(sql.id)
recu.level = recu.level - 1
}