IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

DB2 Admin Scheduler Code !!


IBM Mainframe Forums -> DB2
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
mjadwani2785

New User


Joined: 28 Apr 2009
Posts: 89
Location: Noida , Dublin

PostPosted: Sun Jun 12, 2011 9:02 pm
Reply with quote

Hi,

I am able to activate admin scheduler of DB2 at my site . The code which I wrote was in batch assigned some static values and it worked fine for me.Job got scheduled and were running fine.

Initial testing went fine used few values to experiment with.

Now I am designing ISPF panel to work this thing out but the code here fails:

the code as follows

Code:
address ispexec                                     
"display panel (panadm2) "                         
                                                   
 if (length(jcllib)<>0) then                       
 do                                                 
 do while(length(jclmem)==0 | length(jobwait)==0)   
 address ispexec                                   
"display "                                         
end                                                 
end                                                 
  if (rc==0) then                                   
  call initialise                                   
  else                                             
  call adieu                                       
                                                   
  call connect_db2                                 
  call Add_task                                     
    call adieu                                     
                                                   
                                                   
    adieu:                                         
    exit  /*bye_bye */                             
                                                   
 initialise :                                       
 /* upper dbssid ; upper jcllib                     
 upper jclmem ; upper jobwait                       
 upper desc */                                     
                                                   
                                                   
DB2_SUBSYS='DB2V'                                   
PROC = 'SYSPROC.ADMIN_TASK_ADD'                     
s_rc = 0                                           

if (length(uid)==0) then i_uid=-1               
else i_uid=0                                   
                                               
if (length(pwd)==0) then i_pwd=-1               
else i_pwd=0                                   
                                               
if (length(begts)==0) then i_begts=-1           
else i_begts=0                                 
                                               
if (length(endts)==0) then i_endts=-1           
else i_endts=0                                 
                                               
if (length(maxinvo)==0) then i_maxinvo=-1       
else  i_maxinvo=0                               
                                               
if (length(intval)==0) then i_intval=-1 
else intval=0       

if (length(pit)==0) then i_pit=-1         
else i_pit=0                             
                                         
if (length(ttname)==0) then i_ttname=-1   
else i_ttname=0                           
                                         
if (length(ttcond)==0) then i_ttcond=-1   
else i_ttcond=0                           
                                         
if (length(ttcode)==0) then i_ttcode=-1   
else i_ttcode=0                           
                                         
if (length(dbssid)==0) then i_dbssid=-1   
else                                     
i_dbssid=0                                   
                                             
if (length(pschema)==0) then                 
do                                           
pschema=" "                                 
i_pschema=-1                                 
end                                         
else i_pschema=0                             
                                             
if (length(pname)==0) then i_pname=-1       
else i_pname=0                               
                                             
if (length(pinput)==0) then i_pinput=-1     
else i_pinput=0                             
                                             
if (length(jcllib)==0) then i_jcllib=-1     
else i_jcllib=0                               
                                               
if (length(jclmem)==0) then i_jclmem=-1       
else i_jclmem=0                               
                                               
i_job_wait=0                                   
                                               
if (length(taskname)==0) then i_taskname=-1   
else i_taskname=0                             
                                               
if (length(desc)==0) then i_desc=-1           
else i_desc=0                                 
                                               
RETCD=0 ; retcd_ind=0                         
                                               
MSSG=LEFT(' ',1331);mssg_ind=0                 

return                     
                           
connect_db2 :               
                           
ADDRESS TSO                 
"SUBCOM DSNREXX"           
                           
if rc<>0 then               
 S_RC = RXSUBCOM('ADD','DSNREXX','DSNREXX')                   
                                                             
ADDRESS DSNREXX                                               
                                                             
"CONNECT" DB2_SUBSYS                                         
 If rc <> 0 Then Do                                           
        Say 'Cannot connect to ' DB2_subsys ' RC=' rc         
        Exit(23)                                             
     End                                                     
                                                             
  return                                                     
                                                             
 Add_task:                                                   
                                                             
ADDRESS DSNREXX                                               
'EXECSQL SET CURRENT SQLID=''"'DBADM'"'                       
 if (sqlcode<>0) then                           
 call sql_error                                 
ADDRESS DSNREXX                                 
 'EXECSQL CALL :proc( ',                         
                    ':uid :i_uid,',             
                    ':pwd :i_pwd,',             
                    ':begts :i_begts,',         
                    ':endts :i_endts,',         
                    ':maxinvo :i_maxinvo,',     
                    ':intval :i_intval,',       
                    ':pit  :i_pit,',             
                    ':ttname :i_ttname,',       
                    ':ttcond :i_ttcond,',       
                    ':ttcode :i_ttcode,',       
                    ':dbssid :i_dbssid,',       
                    ':pschema :i_pschema,',     
                    ':pname  :i_pname,',                 
                    ':pinput :i_pinput,',               
                    ':jcllib :i_jcllib,',               
                    ':jclmem :i_jclmem,',               
                    ':jobwait :i_jobwait,',             
                    ':taskname :i_taskname,',           
                    ':desc :i_desc,',                   
                    ':RETCD :retcd_ind,',               
                    ':MSSG :mssg_ind)'                   
                                                         
 say "Return_code=  "retcd                               
 say "Message=      "mssg                               
                                                         
 if (sqlcode<>0) then                                   
 call sql_error                                         
 return                                                             
                                                                   
 sql_error:                                                         
                                                                   
 say sqlcode                                                       
 say sqlstate                                                       
 SAY SQLERRMC                                                       
 SAY SQLERRP                                                       
 Say 'SQLWARN  = 'SQLWARN.0',' || SQLWARN.1',' || SQLWARN.2',' ||, 
                  SQLWARN.3',' || SQLWARN.4',' || SQLWARN.5',' ||, 
                  SQLWARN.6',' || SQLWARN.7',' || SQLWARN.8',' ||, 
                  SQLWARN.9',' || SQLWARN.10                       
 Say 'SQLERRD  = 'SQLERRD.1',' || SQLERRD.2',' || SQLERRD.3',' ||, 
                  SQLERRD.4',' || SQLERRD.5',' || SQLERRD.6         
 exit (sqlcode)       


Now the code is giving error saying SQLCODE=-302.

Postion 12 of the sql call of the procedure has invalid value.

Now here pschema is at position 12 and i dont find any invalid value there.

If anybody can test out the code for me and help me in finding the error.
Back to top
View user's profile Send private message
dick scherrer

Moderator Emeritus


Joined: 23 Nov 2006
Posts: 19244
Location: Inside the Matrix

PostPosted: Mon Jun 13, 2011 12:43 am
Reply with quote

Hello,

The -302 meaning is rather straightforward. Read here:
publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/handheld/Connected/BOOKS/dsnmcj10/2.1.6.110?

If db2 believes there is some kind of invalid value, there is an invalid value. . .

What values are in all of the variables?

Quote:
Now here pschema is at position 12 and i dont find any invalid value there.
I do not understand what this tells me icon_confused.gif
Back to top
View user's profile Send private message
mjadwani2785

New User


Joined: 28 Apr 2009
Posts: 89
Location: Noida , Dublin

PostPosted: Mon Jun 13, 2011 8:51 pm
Reply with quote

Quote:
Now here pschema is at position 12 and i dont find any invalid value there.


I am using here null value for pschema.. or say I am not giving any input to the field in my ispf panel where proc schema is asked and it is returning -302.

While in my other code where I am specifically hardcoding pschema=" " and calling this code from batch this is working.

I traced it compared it both seems to be same. But Still icon_sad.gif
Back to top
View user's profile Send private message
dick scherrer

Moderator Emeritus


Joined: 23 Nov 2006
Posts: 19244
Location: Inside the Matrix

PostPosted: Mon Jun 13, 2011 9:06 pm
Reply with quote

Hello,

Quote:
I am using here null value for pschema..
There is no such thing as a null value. . . A byte may contain any value from x'00' to x'FF' - NONE of these is a "null value".

Look at the exact valu from the batch job (in hex) and the look at the same value online (also in hex). Are they the same? If not, modify the process so that the online uses the same value that works in batch.
Back to top
View user's profile Send private message
mjadwani2785

New User


Joined: 28 Apr 2009
Posts: 89
Location: Noida , Dublin

PostPosted: Sun Jul 03, 2011 7:48 pm
Reply with quote

Quote:
Look at the exact valu from the batch job (in hex) and the look at the same value online (also in hex). Are they the same?


It was quite a learning infact.

I did c2x to find out hex value for both batch and online and both are equal to 40 ?

Is there any other way to pass on null value to sql through REXX ?

Regards,
Manoj K Jadwani
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10873
Location: italy

PostPosted: Sun Jul 03, 2011 8:34 pm
Reply with quote

a simple visual inspection would have show that i_job_wait is not the same as i_jobwait
Back to top
View user's profile Send private message
Nic Clouston

Global Moderator


Joined: 10 May 2007
Posts: 2455
Location: Hampshire, UK

PostPosted: Sun Jul 03, 2011 8:36 pm
Reply with quote

'' (no space between quotes)
Back to top
View user's profile Send private message
mjadwani2785

New User


Joined: 28 Apr 2009
Posts: 89
Location: Noida , Dublin

PostPosted: Sun Jul 03, 2011 9:04 pm
Reply with quote

Thanks Enrico ..It worked...I was searching the error at pos 12.

You are always a help.

Thanks all.

Now I can proceed ahead icon_biggrin.gif
Back to top
View user's profile Send private message
Marso

REXX Moderator


Joined: 13 Mar 2006
Posts: 1353
Location: Israel

PostPosted: Mon Jul 04, 2011 6:39 pm
Reply with quote

One of the ugliest piece of code I ever saw... icon_cry.gif
Here is one of the hidden bugs:
mjadwani2785 wrote:
if (length(intval)==0) then i_intval=-1
else intval=0
Back to top
View user's profile Send private message
mjadwani2785

New User


Joined: 28 Apr 2009
Posts: 89
Location: Noida , Dublin

PostPosted: Mon Jul 04, 2011 6:45 pm
Reply with quote

I accept Marso .. I m not a good coder.. actually m not from a coding backgroud . But still trying.

Your suggestions for writing good readable code will be highly appreciated.

icon_smile.gif
Back to top
View user's profile Send private message
mjadwani2785

New User


Joined: 28 Apr 2009
Posts: 89
Location: Noida , Dublin

PostPosted: Mon Jul 04, 2011 7:29 pm
Reply with quote

and the above bug was corrected in my original code . But still need to know how to make the code more readable .
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10873
Location: italy

PostPosted: Mon Jul 04, 2011 8:02 pm
Reply with quote

start by using capitalization, proper indentation and alignment
do not try to impress people with foreign language show-off
REXX is smarter than c, no need to use the strict (==) compatrison operator

it might work, but it is always safer to put an exit statement before the procedures

Code:

Address ISPEXEC "display panel (panadm2) "                         
if  (length(jcllib)<>0) then ,                                                 
    do while(length(jclmem)=0 | length(jobwait)=0)   
    Address ISPEXEC "display "                                                               
end                                                 
if (rc=0) then ,
    call initialise                                   
else ,                                             
    call adieu                                       
   
call connect_db2                                 

call Add_task                                     

call adieu                                     

exit
                                                   
adieu:                                         
    exit  /*bye_bye */                             
   
initialise :                                       
    /*
    upper dbssid
    upper jcllib                     
    upper jclmem
    upper jobwait                       
    upper desc
    */                                     
                                                                                                   
    DB2_SUBSYS='DB2V'                                   
    PROC = 'SYSPROC.ADMIN_TASK_ADD'                     
    s_rc = 0                                           

    if (length(uid)=0) then i_uid=-1               
    else i_uid=0
   
    if (length(pwd)=0) then i_pwd=-1               
    else i_pwd=0                                   
   
    if (length(begts)=0) then i_begts=-1           
    else i_begts=0                                 
                                               
    if (length(endts)=0) then i_endts=-1           
    else i_endts=0                                 
                                               
    if (length(maxinvo)=0) then i_maxinvo=-1       
    else  i_maxinvo=0                               
                                               
    if (length(intval)=0) then i_intval=-1 
    else intval=0       

    if (length(pit)=0) then i_pit=-1         
    else i_pit=0                             
                                         
    if (length(ttname)=0) then i_ttname=-1   
    else i_ttname=0                           
                                         
    if (length(ttcond)=0) then i_ttcond=-1   
    else i_ttcond=0                           
                                         
    if (length(ttcode)=0) then i_ttcode=-1   
    else i_ttcode=0                           
                                         
    if (length(dbssid)=0) then i_dbssid=-1   
    else i_dbssid=0                                   
                                             
    if (length(pschema)=0) then do
        pschema=" "                                 
        i_pschema=-1                                 
    end                                         
    else ,
        i_pschema=0                             
                                             
    if (length(pname)=0) then i_pname=-1       
    else i_pname=0                               
                                             
    if (length(pinput)=0) then i_pinput=-1     
    else i_pinput=0                             
                                             
    if (length(jcllib)=0) then i_jcllib=-1     
    else i_jcllib=0                               
                                               
    if (length(jclmem)=0) then i_jclmem=-1       
    else i_jclmem=0                               
                                               
    i_jobwait=0                                   
                                               
    if (length(taskname)=0) then i_taskname=-1   
    else i_taskname=0                             
                                               
    if (length(desc)=0) then i_desc=-1           
    else i_desc=0                                 
                                               
    RETCD=0
    etcd_ind=0                         
                                               
    MSSG=LEFT(' ',1331);mssg_ind=0                 

    return                     
                           
connect_db2 :               
                           
    Address TSO "SUBCOM DSNREXX"           
                           
    if rc<>0 then ,
        S_RC = RXSUBCOM('ADD','DSNREXX','DSNREXX')                   
                                                             
    Address DSNREXX "CONNECT" DB2_SUBSYS                                         
    If  rc <> 0 Then Do                                           
        Say 'Cannot connect to ' DB2_subsys ' RC=' rc         
        Exit(23)                                             
    End                                                     
    return                                                     
                                                             
Add_task:                                                   
    Address DSNREXX 'EXECSQL SET CURRENT SQLID=''"'DBADM'"'                       
    if (sqlcode<>0) then ,                           
        call sql_error                                 
    Address DSNREXX 'EXECSQL CALL :proc( ',                         
                    ':uid :i_uid,',             
                    ':pwd :i_pwd,',             
                    ':begts :i_begts,',         
                    ':endts :i_endts,',         
                    ':maxinvo :i_maxinvo,',     
                    ':intval :i_intval,',       
                    ':pit  :i_pit,',             
                    ':ttname :i_ttname,',       
                    ':ttcond :i_ttcond,',       
                    ':ttcode :i_ttcode,',       
                    ':dbssid :i_dbssid,',       
                    ':pschema :i_pschema,',     
                    ':pname  :i_pname,',                 
                    ':pinput :i_pinput,',               
                    ':jcllib :i_jcllib,',               
                    ':jclmem :i_jclmem,',               
                    ':jobwait :i_jobwait,',             
                    ':taskname :i_taskname,',           
                    ':desc :i_desc,',                   
                    ':RETCD :retcd_ind,',               
                    ':MSSG :mssg_ind)'                   
                                                         
    say "Return_code=  "retcd                               
    say "Message=      "mssg                               
                                                         
    if (sqlcode<>0) then ,                                   
        call sql_error                                         
    return                                                             

sql_error:                                                                                                                           
    say sqlcode                                                       
    say sqlstate                                                       
    SAY SQLERRMC                                                       
    SAY SQLERRP                                                       
    Say 'SQLWARN  = 'SQLWARN.0',' || SQLWARN.1',' || SQLWARN.2',' ||, 
                     SQLWARN.3',' || SQLWARN.4',' || SQLWARN.5',' ||, 
                     SQLWARN.6',' || SQLWARN.7',' || SQLWARN.8',' ||, 
                     SQLWARN.9',' || SQLWARN.10                       
    Say 'SQLERRD  = 'SQLERRD.1',' || SQLERRD.2',' || SQLERRD.3',' ||, 
                     SQLERRD.4',' || SQLERRD.5',' || SQLERRD.6         
    exit (sqlcode)       
   


REXX sometimes is too smart and makes easy to misunderstand things

for example one thing that baffles me is the implicit continuation of the if

Code:

if <logical expression> then
<some statement>

is the same as
if  <logical expression> then
    <some statement>

and the same as
if  <logical expression> then ,
    <some statement>


the first form needs two <sighting> passes
( usually the statements after an if or a do should be indented )
the second form is a bit better

my preference goes to the third form
a simple comma makes thgings much more readable

also for the simple if then else to set flags

my preference goes to

Code:

<flag> = <value for the FALSE>
if  <logical expression> then ,
    <flag> = <value for the TRUE>
   
or
<flag> = ( <logical expression > ) * <value for the TRUE>

as in
i_taskname = ( length(taskname)=0 ) * -1   


it makes easier to initialize all the flags in one place and to take care of the exceptions later on
Back to top
View user's profile Send private message
Marso

REXX Moderator


Joined: 13 Mar 2006
Posts: 1353
Location: Israel

PostPosted: Mon Jul 04, 2011 8:07 pm
Reply with quote

Code:
address ispexec                                     
"display panel (panadm2) "                         
                                                   
 if (length(jcllib)<>0) then                       
 do                                                 
 do while(length(jclmem)==0 | length(jobwait)==0)   
 address ispexec                                   
"display "                                         
end                                                 
end

  1. address ispexec, when used alone on a line, permanently changes the commands destination.
    (well, not exactly permanently, but until a return or exit or another address)
    You must know, at given given time, to which environment you are connected.
    Use address ispexec "display..." instead.
  2. use strict operators only for strings, not numerics (unless you want to make a difference between 01 and 1 for example).
    Most of the time, you don't even need strict operators.
  3. Instead of checking for the length of a variable, you can check the variable itself:
    JCLLIB = '' instead of length(JCLLIB)=0
  4. Logical validation should be placed in the panel (using IF and VER statements)
    You can check that dsnames and member names are valid, too.
  5. Empty DO-END are just useless.
Code:
  if (rc==0) then                                   
  call initialise                                   
  else                                             
  call adieu                                       
                                                   
  call connect_db2                                 
  call Add_task                                     
    call adieu
  1. Follow indentation rules!
  2. I would connect to DB2 before displaying the panel.
    If there is any problem with DB2, no need to display the panel and let the user sweat on filling all the fields,
    just to send him away eventually.
  3. Organize your calls so there are one after the other if they are always executed one after the other.

So far, here is how I would code the program:
Code:
Call connect_db2
Address ispexec "display panel (panadm2) "
If RC = 0 Then Do
   Call initialise
   Call Add_task
End
Exit

If you need some help about IF and VER in panels, read the books, search the forum then ask
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10873
Location: italy

PostPosted: Mon Jul 04, 2011 8:12 pm
Reply with quote

icon_redface.gif
Guilty as charged, I forgot to tell to check the return code..

Return code checking is mandatory after the invocation of any foreign service

it comes so natural that i forget to tell

and if the cleanup code is short I prefer often the other way around

Address ISPEXEC "display panel (panadm2) "
if RC \= 0 then do
<clenup and terminate >
end


but my true preference goes to strict structured programming,
thats why I alway use wrappers around ISPF and TSO environments

so that I can code ...

Code:
Do while ( $ispex("DISPLAY PANEL(MYPANEL)" = 0 )
    < normal processing >
end

....


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
$tsoex:                                                                 
   tso_0tr = trace("O")                                                 
   Address TSO arg(1)                                                   
   tso_0rc = rc                                                         
   trace value(tso_0tr)                                                 
   return tso_0rc                                                       
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
$ispex:                                                                 
   isp_tr = trace("O")                                                 
   Address ISPEXEC arg(1)                                               
   isp_rc = rc                                                         
   trace value(isp_tr)                                                 
   return isp_rc                                                       
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
$isred:                                                                 
   isr_tr = trace("O")                                                 
   Address ISREDIT arg(1)                                               
   isr_rc = rc                                                         
   trace value(isr_tr)                                                 
   return isr_rc                                                       
Back to top
View user's profile Send private message
Marso

REXX Moderator


Joined: 13 Mar 2006
Posts: 1353
Location: Israel

PostPosted: Mon Jul 04, 2011 8:34 pm
Reply with quote

Code:
i_taskname = ( length(taskname)=0 ) * -1 
That was supposed to be the second part of my post!
It works because
Quote:
The comparison operators compare two terms and return the value 1 if the result of the comparison is true, or 0 otherwise.

Coding
Code:
    i_uid     = ( length(uid)=0     ) * -1
    i_pwd     = ( length(pwd)=0     ) * -1
    i_begts   = ( length(begts)=0   ) * -1
    i_endts   = ( length(endts)=0   ) * -1
    i_maxinvo = ( length(maxinvo)=0 ) * -1
    i_intval  = ( length(intval)=0  ) * -1
or
Code:
    i_uid     = ( uid=''     ) * -1
    i_pwd     = ( pwd=''     ) * -1
    i_begts   = ( begts=''   ) * -1
    i_endts   = ( endts=''   ) * -1
    i_maxinvo = ( maxinvo='' ) * -1
    i_intval  = ( intval=''  ) * -1
makes the code much easier to read...
And less bugged...

Code:
Address DSNREXX 'EXECSQL SET CURRENT SQLID=''"'DBADM'"'
There are too many quotes. It is now difficult to understand if DBADM is a variable or the value.
Code:
Address DSNREXX 'EXECSQL SET CURRENT SQLID="'DBADM'"' /*variable*/
Address DSNREXX 'EXECSQL SET CURRENT SQLID="DBADM"'   /*value*/
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10873
Location: italy

PostPosted: Mon Jul 04, 2011 8:42 pm
Reply with quote

Quote:
There are too many quotes. It is now difficult to understand if DBADM is a variable or the value.


that' s one of the reasons that for strings I prefer to use <"> rather than <'>

and I just did not feel to interpret the quotes/apostr mess
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> DB2

 


Similar Topics
Topic Forum Replies
No new posts run rexx code with jcl CLIST & REXX 15
No new posts Compile rexx code with jcl CLIST & REXX 6
No new posts changing defaults in db2 admin - Unlo... DB2 0
No new posts REXX code to expand copybook in a cob... CLIST & REXX 2
No new posts OPCP scheduler questio IBM Tools 0
Search our Forums:

Back to Top