2014 Aug 21 11:55 AM
Friends,
I am facing weird issue in my production system i.e. one of the code block which was bounded in IF condition is getting triggered. However, as per the data that I have in my system this IF condition should skip that code block.
Let me give you code and execution flow here:
I have Program A in which I am submitting Program B in background mode to selected server. This Program A will be executed by end user in Background mode.
call function 'JOB_OPEN'
exporting
jobname = job_name
importing
jobcount = job_number
exceptions
cant_create_job = 01
invalid_job_data = 02
jobname_missing = 03.
if sy-subrc = 0.
submit program B
via job job_name number job_number
with p_sched = sched
with period_p = period
with fyear_p = fyear
with username = ruser
and return.
call function 'JOB_CLOSE'
exporting
jobcount = job_number
jobname = job_name
sdlstrtdt = start_date
sdlstrttm = start_time
targetserver = l_targetserver "V05++
exceptions
cant_start_immediate = 01
invalid_startdate = 02
jobname_missing = 03
job_close_failed = 04
job_nosteps = 05
job_notex = 06
lock_failed = 07.
endif.
As you can see in code, I am passing job to run on l_targetserver. This program also releases some other jobs on other programs.
In Program B, I have code like this:
Top Include.
start-of-selection.
perform routine1 using p_fyear. "THIS HAS SOME SELECT QUERIES AND OTHER CODE and THERE IS NO ISSUE WITH IT. THIS ROUTINE IS
ALSO HAVING ONE AND ONLY 'CLEAR' statement on DELTA_FLAG.
perrform routine2.
form routine2.
loop itab into wa. " This itab was populated in routine1
perform get_flag." WE ARE PASSING VALUE TO DELTA_FLAG VARIABLE HERE. YOU CAN CHECK CODE BELOW.
perform process_data. "CHECK THIS ROUTINE
peform update_records.
endloop.
endform.
Form Get_FLag.
select * from dbtable into localtable where <condition>. " THIS QUERY RETURNS SOME DATA AND MY FLAG WILL BE SET AS 'X'.
if sy-subrc = 0.
delta_flag = 'X'. "THis one declared in top include.
endif.
EndForm.
Form Process_Data.
Perform get_dataset1.
while counter <> 0. " Variable Counter declared in top include and default value is 20. Value will be decreased in side this loop. No issues with it.
if wa-fld1 = '1'. "Check value of one of the field.
continue.
endif.
perform get_delta_data. " We have Unwanted ABAP code (for my scenario) here.
endwhile.
Endform.
form update_records.
call function 'FUNCTION' in update task exporting par1 = itab.
commitwork
endform.
form get_delta_data.
if delta_flag is initial.
select data from BSEG into i_bseg where <condition>. " This query is getting triggered in my system.
endif.
endform.
All my data objects were declared in Top include of the program. Subroutines with their parameters were same as above code. I am not using any sub-routine second time or out-side of this program. As shown, this program updates records to one of the table with UPDATE function module IN UPDATE TASK and there is COMMITWORK after that. This task is part of
As you could understand, DELTA_FLAG is having 'X' but query on BSEG is getting triggered. We are not clearing this variable after populating 'X' to it. I can see this query from Program B captured in ST12 trace results. (Verified it multiple times)
I did this analysis:
1. Ran this process in foreground with debugging, then there is no issue.
2. Debugged 'Finished' job of my production system, but I dont see this code triggered in Debug mode.
3. Replicated same execution process in our non-production environments, but there is no issue.
Let me know if you need any other details.
Thanks for your time.
Regards,
Naveen
2014 Aug 21 12:18 PM
Hi,
It's probably the UPDATE TASK not completing in time.
But there's a much bigger issue here: I see that none of your subroutines (bar one) has parameters.
The subroutines manipulate global variables , so it is hard to see (without diving into the code) exactly what is being changed where.
Let's not even start on the commenting and indentation.
It might be a matter of personal taste, but I find the above code almost impossible to follow.
Give it a complete rewrite and I bet your problem will disappear.
good luck
Paul
2014 Aug 21 12:18 PM
Hi,
It's probably the UPDATE TASK not completing in time.
But there's a much bigger issue here: I see that none of your subroutines (bar one) has parameters.
The subroutines manipulate global variables , so it is hard to see (without diving into the code) exactly what is being changed where.
Let's not even start on the commenting and indentation.
It might be a matter of personal taste, but I find the above code almost impossible to follow.
Give it a complete rewrite and I bet your problem will disappear.
good luck
Paul
2014 Aug 21 12:39 PM
No, I don't believe it's a matter of personal taste. I'd mercilessly reject this code if any external "consultant" tried to deliver it, without so much as asking what it does and looking at any acceptance test results; he/she would be fixing it on own time, and I would try to make sure the person is NEVER hired to do anything again. Sorry, Naveen, this is IMO blatantly shoddy work; utterly unacceptable.
cheers
Janis
2014 Aug 21 1:03 PM
Janis,
I composed simplified version of 2050 lines main program and top include of 300 lines. I cannot avoid those subroutines as I am thinking issue is around sub-routines.
Unfortunately, there is no way that I can share my program with you. On that note, please believe in me that there are valid reasons for this code structure. Details about that is irrelevant to this issue. I will find some time after this issue and happy to share it with you!
May be I can do better formatting in my post and I tried that in one of my reply. Still, I don't see blanks lines (for better readability) once I convert my code as SQL code lines in 'advanced editor'.
Regards,
Naveen
2014 Aug 21 12:33 PM
the only reason I can think of is that below statement does not return any data in the background sessions.
select * from dbtable into localtable where. " THIS QUERY RETURNS SOME DATA AND MY FLAG WILL BE SET AS 'X'.
if sy-subrc = 0.
delta_flag = 'X'. "THis one declared in top include.
endif.
Offcourse we cannot see what you are trying to select and what the condition is. Are these the updated records you have updated in a previous loop pass ?
2014 Aug 21 12:50 PM
Hi Peter Jonker,
Selection is not based on the previous loop. We are just checking from previous run.
Fig: Actual Query from program. We are using tabname variable in update query as well.
Couple of notes on this:
> There is no clear statement on DELTA_LOAD within loop
> in debug mode I can see value 'X' in this DELTA_LOAD for first iteration. (Unfortunately, I cannot hit UPDATE query in production. No go to statement access).
You said, "Offcourse we cannot see what you are trying to select and what the condition is".
Yes, I agree. This is very strange issue which I cannot replicate in other systems also. I did many trace reviews, now thinking about passing DELTA_FLAG with parameters of GET_DELTA_DATA routine.
Thanks for your thoughts.
Regards,
Naveen
2014 Aug 21 1:01 PM
Ok, well starnge indeed, then I have no more suggestions on this. That could be the only reason to my opinion.
Furthermore a question I have about your code: why do you have perform get_flag in the loop if it only needs to be executed once ?
I also see that you use delta_load variable in the screenprint and in other source code extracts it is called delta_flag. Could that be the reason ?
2014 Aug 21 1:12 PM
Jonker,
Screen shot is from original program and I just referred delta_load as delta_flag in my post.
And, you are right we should move this query out side the loop (one of our change request )
Regards,
Naveen
2014 Aug 21 12:34 PM
Thanks Paul.
Thanks for your input. I was thinking about moving code related DELTA_FLAG into one routine (clear and data passing) and then using parameters to move that value to other routine where I am using. I am not suspecting UPDATE FM because, I am just submitting it as separate task and nothing to do with flag here.
Here's I tried same code with better format.
include zglr6000_top. " DELTA_FLAG declared in it
start-of-selection.
perform routine1 using p_fyear. " Clear Statement for DELTA_FLAG Variable
perform routine2.
form routine2.
loop at itab into wa.
perform get_flag. " WE ARE PASSING VALUE TO DELTA_FLAG VARIABLE HERE
perform process_data. " USING DELTA_FLAG HERE
perform update_records.
endloop.
endform.
form get_flag.
select * from dbtable into localtable where <condition>. " THIS QUERY RETURNS SOME DATA AND MY FLAG WILL BE SET AS 'X'.
if sy-subrc = 0.
delta_flag = 'X'.
endif.
endform.
form process_data.
while counter <> 0. " Variable Counter declared in top include and default value is 20.
if wa-fld1 = '1'.
continue.
endif.
counter = counter - 1.
perform get_delta_data. " We have Unwanted ABAP code (for my scenario) here.
endwhile.
endform.
form update_records.
call function 'FUNCTION' in update task exporting par1 = itab.
commit work.
endform.
form get_delta_data.
if delta_flag is initial.
select data from bseg into i_bseg where <condition>. " This query is getting triggered in my system.
endif.
endform.
Regards,
Naveen
2014 Aug 21 1:03 PM
What is the definition of DELTA_FLAG in include? Also does it set the DELTA_FLAG to X for the first time when it goes to form get_flag
select * from dbtable into localtable where <condition>. " THIS QUERY RETURNS SOME DATA AND MY FLAG WILL BE SET AS 'X'.
if sy-subrc = 0.
delta_flag = 'X'.
endif.
Also is there a possibility that your Select on the table dbtable (which is this table?) is failing because of which the flag is not setting at all..And there is nothing to set this flag after this is called once.
2014 Aug 21 1:12 PM
.... " Clear Statement for DELTA_FLAG Variable
Why, is it being set somewhere before START-OF-SELECTION..?
select * from dbtable into localtable where <condition>. " ....
Is it INTO or INTO TABLE? If the latter, wher's the ENDSELECT located?
... " THIS QUERY RETURNS SOME DATA AND MY FLAG WILL BE SET AS 'X'.
Bold claim, but if it always returns some data, why do you need a flag in the first place...? Edit in: Ok, the screenshot explains, but adds mystery and complexity - where and how does the tabname get the value...?
fyear_p in SUBMIT and p_fyear in code... is that intended..?
I do realise now that some of this is pseudo-code and maybe I was too harsh in my previous post, but believe me, the ABAP IF statement conditions do work...
cheers
Janis
Message was edited by: Jānis B
2014 Aug 21 1:17 PM
CHAR1 is type of delta_flag.
And, as I replied to Peter Jonker, I have data in (tabname) and sy-subrc is ZERO and flag is 'X'.
There is no issue in foreground or the finished job debug!!
Regards,
Naveen
2014 Aug 21 1:31 PM
Clear statement is in first subroutine which is right after the start-of-selection. yes, I can move it into get_flag. Do you see any issue with it?
In actual program, we are selecting data into variable (I posted one screen shot of that query). This source table is having data and where condition input are not having any formatting/conversion issues.
"fyear_p in SUBMIT and p_fyear in screen shot.. is it intended..?" - yes (using secondary variables from selection screen inputs)
yes, I think issue might be 'not having' parameters for subroutine to carry delta_flag. I am going to check that (unfortunately, I am not able to prove it to rely on this deployment) but no other data objects are having this issue.
Regards,
Naveen
2014 Aug 21 1:54 PM
I shouldn't have been so harsh and quick to condemn - for that I'm sorry.
If I would inherit this work, I'd do the same as I do with every procedural "report" programm having global data definitions and little to no form interfaces I have to touch - start by investing as much time as necessary to eliminate as much of globals as possible - preferrably all of them, and defining all interfaces. Commenting globals out one at the time, recompiling to find all uses, building up the form routine interfaces, introducing formroutine MAIN to define the data truly global to the whole process. Every parameter and every select option would be passed down the call chain to the place it is used... No formal and actual parameter would have the same name, everything would get proper typing and naming... This kind of programms tend to accumulate lots of dead code and unnecessary data definitions over time - they'd be eleminated in the process.
This is no golden bullet and can (and therefore will) introduce an occasional new error and for that reason a complete rewamp would not be supported be every developer/team lead... In my experience (60-80% of it is maintenace work on a more than 10 years old custom procedural code base; much of it of poor to shockingly poor quality) it ends up saving time.
It also tends to produce wide and, without restructuring, sometimes "illogical" looking interfaces... But it gives at the end that sweet feeling:- now I am in control of this stuff...
Good luck
Janis
Message was edited by: Jānis B
2014 Aug 21 2:15 PM
Hey - It's ok, no worries.
Thanks for your thoughts on this problem. I will update this thread with my findings/progress in system.
Regards,
Naveen
2014 Aug 22 1:57 AM
Hi,
If it was me, I would recode the whole thing. I'm certain the problem would disappear, and you'd end up with nice maintainable code to hand down to future generations.
I realize it's not always possible though !
cheers
Paul
2014 Aug 22 7:48 AM
I forgot the one bit, which might actually have been useful: I'd be moving the if delta_flag is initial. out of form get_delta_data, before perform get_delta_data.Since you are calling in nested loops there, every little bit of run-time counts, and "philosophically" I feel - procedure should do what its name promises it will, and not check whether it's "appropriate time" to do it
cheers and good luck
Jānis
2014 Sep 03 9:37 AM
Fixed those minor bugs that we discussed above (IF condition outside to routine, Select-Loop) and applied changes across the program to use 'Using, Changing, Tables' parameters to switch to logic in sub-routines.
Yet to be deployed to see results as I am not facing this issue in other systems.
I will update this discussion with results!
Thanks to all,
Naveen Inuganti