Pause-Café Volubis

pause-café

rendez-vous technique
Pause-Café est une réunion technique
destinée aux informaticiens sur plateforme IBM i.
Elle a lieu 3 à 4 fois par an : en Bretagne et sur internet.

Pause-café #39

Janvier 2006


V5R40 ...

Quelques nouvelles de la version 5.4 (prévue pour début 2006) avec dans la foulée, une conférence technique (pour l'Europe, en Italie) annoncée en Février 2006.

  • Une nouvelle machine virtuelle Java (basée sur PASE)
    -> Voyez le document iSeries application development directions (fichier PDF, modifié en septembre 2005) ,
    particulièrement la page 9 qui explique la nouvelle JVM et plus encore...

  • SQL en format libre dans le RPG en format libre, support du XML en natif et Move Corresponding

  • Gestion de la base de données et des index simplifiée ( performances )

  • Nouvelle gestion des sous systèmes (nous allons revoir quelques fondamentaux)

  • Nouveautés sécurité et détection d'intrusions

  • Nouveau support des applications SNA sur IP

  • Nouvel assistant pour l'administration WEB et la gestion des performances du serveur Apache.

  • des avancées I5/OS allant vers plus de disponibilité.

  • Nouveautés CL :

    • Possibilité de faire sous programmes

      • SUBR/ENDSUBR
      • CALLSUBSR
      • RTNSUBR
    • Support des pointeurs  pour une utilisation plus simple de certaines API.

      • DCL &PTR TYPE(*PTR)
      • Fonctions %ADDRESS(nom-variable) qui renseigne un pointeur
      • et %OFFSET(pointeur) pour incrémenter/decrémenter un pointeur

|                                                            

Gestion des Sous-systèmes.



 La création d'un sous système se fait à l'aide de la commande CRTSBSD 

  La mémoire principale du système est divisée en pools mémoire :
     *BASE pour le batch, *INTERACT pour l'interactif , *SPOOL le spool
      *SHRPOOLn (1 à 32) pour un découpage personnalisé.

  Chaque sous système peut lui même se découper en pool de sous système,
   chacun d'entre eux utilisant un pool mémoire différent.

  par exemple, pour un sous système utilisateur :

    - un pool du sous système (1) utilisant *INTERACT, pour les écrans.
    - un pool du sous système (2) utilisant *BASE pour les batch (JOBQ)

.........................................................................
: CRTSBSD SBSD(SBSUSER)  POOLS(  (1 *INTERACT)                          :
:                                (2 *BASE)      ) TEXT('SBS de texte')  :
:.......................................................................:

   un tel sous système acceptera les sessions interactives (lien entre
    le sous système et des terminaux) et les travaux batch (lien avec JOBQ)


                           Gestion des sous-systèmes 
                                                            Système:   S44B0164 
 Indiquez vos options, puis appuyez sur ENTREE. 
   4=Arrêter sous-système   5=Afficher description de sous-système 
   8=Gérer les travaux d'un sous-système 

                    Mémoire    --------Pools de sous-système--------- 
 Opt  S-système   totale (ko)   1   2   3   4   5   6   7   8   9  10 
      QBATCH              0     2                                     
      QCMN                0     2       ############################## 
      QCTL                0     2       # la commande WRKSBS affiche # 
      QINTER              0     2   4   #  un tableau croisé     # 
      QPGMR               0     2   2   #                     # 
      QSPL                0     2   3   #  sous-système/pools   # 
      QSYSWRK             0     2       #                mémoire   # 
      QXFPCS              0     2       ############################## 

                                                                            Fin 
 Paramètres ou commande 
 ===>                                                                           
 F3=Exit   F5=Réafficher   F11=Données système   F12=Annuler 
 F14=Gérer état du système 




   il faudra donc ensuite établir une table de routage afin de rediriger
    les travaux dans le pool de sous système 1 ou 2.



 le choix d'une "route", se fera grace à la donnée de routage (RTGDTA) :

    QCMDI, par défaut dans les JOBD associées aux utilisateurs
    QCMDB, par défaut dans le paramètre RTGDTA de la commande SBMJOB



 la commande ADDRTGE permet de construire cette table de routage, elle pemet
  aussi d'indiquer le programme système d'initialisation du travail
  (sauf cas particulier, utiliser le processeur de commandes QCMD)



 ADDRTGE SBSUSER SEQNBR(10) CMPVAL(QCMDI) PGM(QCMD) CLS(QINTER) POOLID(1)

 ADDRTGE SBSUSER SEQNBR(20) CMPVAL(QCMDB) PGM(QCMD) CLS(QBATCH) POOLID(2)



  rappel: la classe indique des attributs sur le plan des performances




 le lien entre un sous système et une JOBQE se fait à l'aide de la commande
   ADDJOBQE 

   CRTJOBQ JOBQUSER

   ADDJOBQE SBSD(SBSUSER) JOBQ(JOBQUSER)



 le lien entre un sous système et un/des terminaux  se fait avec la commande
   ADDWSE 

   la création du terminal doit être automatique, sinon CRTDEVDSP

   ADDWSE SBSD(SBSUSER) WRKSTN(DSP02)

   on peut aussi demander au sous système de s'occuper de tous les terminaux
   (cas de QINTER) par ADDWSE ... WRKSTNTYPE(*ALL)

   en cas de conflit (deux sous système veulent le même objet), c'est le
    dernier démarré qui l'obtient (vérifier sur l'écran de SIGNON)


 WRKSYSSTS vous montre les POOLS mémoire (utilisés par les sous-systèmes)


 ..................................................................
 : Pool    Taill     Taille   Activ  BD       BD   Non BD  Non BD :
 : syst     pool    réservée  maxi   Taux   Pages   Taux   Pages  :
 :   1     123,6       1383    +++     0,0    0,0    0,8     5,6  :
 :   2     807,9          0      4     0,4    2,7    7,1    39,7  : 7,5 
 :   3      10,2          0      1     0,0    0,1    0,0     0,2  : 0,0 
 :   4      61,7          0      1     0,1    0,3    3,6    20,8  : 3,7 
 :................................................................:
     Pour chaque pool(autre que le pool 1 qui est réservé à l'OS),
       la somme des taux BD + Non BD doit être < à 20/25

  Pour une analyse plus fine sur une machine récente, utilisez la formule suivante
       Interactif : 5 + (T x 0,5)
Batch : 10 + (T x 2,0) ou T représente le nb de thread


Il
s'agit ici, d'indiquer le taux de pagination (à rapprocher du niveau d'activité, colonne 4)

- si le rapport taille mémoire/niveau d'activité est trop faible, le système pagine
- s'il est trop important, vous avez des job en attente de traitement (innéligibles)

 
un paramétre important est accessible sur cette commande (par F11)  ==> option de pagination

avec *CALC, vous enclanchez l'expert cache qui conserve en mémoire les fichiers les plus utilisés.

la V5R30 apporte un gain sous SQL


Si 1/ vous utilisez l'expert cache dans le pool mémoire ou s'exécute la requête

2/ votre requête est traitée par SQE (le nouveau moteur voir
 http://www-1.ibm.com/servers/eserver/iseries/db2/sqe.html )

L'ancien moteur SQL (CQE) considérait comme taille mémoire potentielle le résultat du calcul taille mémoire/niveau d'activité,
ce qui pouvait induire une mauvaise utilisation de la mémoire
quand le niveau d'activité était mal renseigné
ou avec l'ajustement automatique (QPFRADJ)


Le nouveau moteur, utilise les statistiques de l'expert cache et divise la taille mémoire par le nombre de travaux moyen
(constaté concurrents en CPU), ce qui est forcément plus juste.


|

Gestion des Dates 

 

Comparatifs des ordres de manipulation de dates

  • On ne peut utiliser l'arithmétique temporelle qu'avec des dates, des heures, des horodatages

    • Les dates
      • Type DATE sous SQL, type L avec SDD
      • comprises entre 1er Janvier de l'AN 1 et 31 Décembre 9999
      • le format n'est qu'un critère d'affichage et est un paramètre SQL (strsql), ODBC, JDBC, etc..
        => Toujours *ISO par défaut !
        • *ISO  -> 'yyyy-mm-dd'
        • *EUR -> dd.mm.yyyy'
        • *DMY-> 'dd/mm/yy' (entre 1940 et 2039)
      • Constantes : au format par défaut.
        • en SQL (fonction du paramétrage)
          'yyyy-mm-dd', par exemple select * from PAUSECAFE where datepause = '2006-01-17'
        • en RPG (fonction de DATFMT en spécif H, sinon *ISO)
          encadrer la constante de D'     ' (D'yyyy-mm-dd') , par exemple
          D  wdate               S                INZ(D'2006-01-17')
    • Les heures
      • Type TIME sous SQL, type T avec SDD
      • comprises entre 0 heures (00:00:00) et Minuit (24:00:00)
      • le format le plus simple est *HMS (hh:mm:ss)
      • le format par défaut est *ISO (hh.mm.ss)
      • Constantes
        • en SQL, au format par défaut entre quotes 'hh.mm.ss'
        • en RPG (TIMFMT en spécif H), encadré de T'                 '
    • Horodatage
      • Type TIMESTAMP sous SQL, type Z sous SDD
      • Contient Date + Heure avec une précision de 6 décimales après la seconde
      • format *ISO -> 'yyyy-mm-dd-hh.mm.ss.cccccc'
      • Constantes
        • en SQL, au format par dfaut entre quotes
        • en RPG , encadré de Z'        
  • Valeur NULLE
    Ce n'est pas spécifique aux dates, mais c'est souvent lié (on préfère assigner la valeur nulle à date de départ qu'une date fictive)             
    • ALWNULL avec SDD
    • par défaut avec SQL (not null pour l'interdir)
    • en programmation :
      • RPG : Indiquez ALWNULL(*USRCTL) en spécif H et utiliser la fonction %NULLIND()           
      • SQL : indiquez :variable:indic pour chaque variable recue lors d'un select
        indic est binaire sur 5 chiffres et contient :
        •  0 : la variable associée à :indic a un contenu significatif 
        • -1 : la variable contient la valeur nulle 
        • -2 : SQL a assigné la valeur nulle suite à une erreur de mappage.

  • les calculs peuvent se faire sous la forme
    1. date + durée = date
    2. date - durée = date
    3. date - date = durée

    4. heure + durée = heure
    5. etc ..

  • les durées peuvent être exprimées de manière explicite avec
    •  une valeur numérique entière n et :

      • Pour SQL
        n YEARS n MONTHS n DAYS
        n HOURS n MINUTES n SECONDS
      • Exemple :
        select * from commandes where datliv = datcde + 2 MONTHS + 10 DAYS


      • Pour RPG
        %YEARS(n) %MONTHS(n) %DAYS(n)
        %HOURS(n) %MINUTES(n) %SECONDS(n)
      • Exemple :
      • /free
          datliv = datcde + %MONTHS(2) + %DAYS(10);
        /end-free

  • en SQL les durées résultat (datcde - datliv) seront toujours exprimées sous la forme AAAAMMJJ, où :
    • AAAA représente le nombre d'années
      MM le nombre de mois
      JJ le nombre de jours
    • Ainsi, si SQL affiche 812, il faut comprendre 8 mois, 12 jours
    • 40301 signifie 4 ans , 03 mois, 01 jour (attention SQL risque d'afficher 40.301)

  • en RPG les durées résultat (datcde - datliv) sont exprimées en une seule unitée, indiquée en argument de la fonction %DIFF
    • Exemple :
    • /free
        ecartenjours = %DIFF(datcde : datliv : *DAYS);
      /end-free

Fonctions liées aux dates

SQL Retourne Exemple SQL RPG Exemple RPG
DATE(x)
X doit être une chaîne au format SQL en cours
une date DATE(
substr(digits(dat8), 7, 2)
 concat '/' concat
substr(digits(dat8), 5, 2)
 concat '/' concat
substr(digits(dat8), 3, 2) )
%DATE(x:*FMT) wdate =%DATE(
datchar:*DMY) ;
DAY(D)
DAYOFMONTH(D)
 la partie jour de D DAY(DATCDE) %SUBDT(d:*D) jj = %SUBDT(
 DATCDE:*D) ;
MONTH(D) la partie mois de D 

MONTH(current date)

%SUBDT(d:*M) mm = %SUBDT(
%date():*M) ;
YEAR(D)  la partie année  de D  YEAR(current date -                    DATCDE) %SUBDT(d:*Y) mm = %SUBDT(
DATCE:*Y) ;
DAYOFYEAR(D) le n° de jour dans l'année (julien) DAYOFYEAR(datdep)
DAYOFWEEK(D) le N° de jour dans la semaine
(1 = Dimanche, 2=Lundi, ...)
DAYOFWEEK(ENTRELE)
DAYOFWEEK_ISO(D) retourne le N° de jour dans la semaine
(1 = Lundi)
DAYOFWEEK_ISO(ENTRELE)
DAYNAME(d) retourne le nom du jour de d (Lundi, Mardi, ...)
DAYNAME(datcde)
MONTHNAME(d) * retourne le nom du mois de d (Janvier, Février, ...)
MONTHNAME(datcde)
EXTRACT(day from d) Extrait la partie jour de D (aussi Month et Year)
EXTRACT(MONTH from datcde)
cf %SUBDT( )
DAYS(D) retourne le nbr de jours depuis 0001-01-01 DAYS(datcde)- DAYS(datliv)

jours = %DIFF(
D'0001-01-01 : datcde : *DAYS) ;

QUARTER(D) retourne le n° du trimestre(1-4) QUARTER(DATEFIN)
WEEK(D) retourne le n° de semaine
(Attention le 1er Janvier est semaine 1)
WHERE
WEEK(DATLIV)= WEEK(DATCDE)
WEEK_ISO(D) retourne le n° de semaine
(la semaine 1 est celle qui possède un JEUDI dans l'année.)
WHERE
WEEK_ISO(DATLIV)= 1
CURDATE() retourne la date en cours, comme CURRENT DATE WHERE
DATLIV = CURDATE()-1 DAY
%DATE() if datcde > %date();
CURTIME() retourne l'heure en cours, comme CURRENT TIME   %TIME()
NOW() retourne le timestamp en cours   %TIMESTP()
JULIAN_DAYS(d) retourne le nbr de jours qui sépare une date du 1er Janv. 4712 av JC.
JULIAN_DAYS(datcde)
Test de la validité d'une zone caractère ou numérique contenant une date. TEST(DE) TEST(DE) datchar;
if %error ;
  .....
endif;

Fonctions liées aux heures

Fonction(x) Retourne  Exemple RPG
TIME(T) une heure TIME(
substr(digits(h6), 1, 2)
 concat ':' concat
substr(digits(h6), 3, 2)
 concat ':' concat
substr(digits(h6), 5, 2) )
%TIME()
HOUR(T)
retourne la partie heure de T HOUR(Pointage) %SUBDT(T:*H)
MINUTE(D) retourne la partie minute de T

 

%SUBDT(T:*Mn)
SECOND(T) Retourne la partie secondes de T   %SUBDT(T:*S)
EXTRACT(hour from t)  la partie heure de T (aussi MINUTE et SECOND)
EXTRACT(SECOND from pointage)
Test de la validité d'une zone caractère ou numérique contenant une heure TEST(TE)

Fonctions liées aux Timestamp

Fonction(x) Retourne  Exemple RPG
TIMESTAMP(T) un timestamp (date - heure - microsecondes) TIMESTAMP('
1999-10-06.15.45.00.000001 ')
%TIMESTP()
TIMESTAMP
(D T)
un timestamp (microsecondes à 0) TIMESTAMP(datcde heure)
TIMESTAMP_ISO(x) 

un timestamp à partir de x
 Si x est une date, l'heure est à 00:00:00
 Si x est une heure, la date est à aujourd'hui.
TIMESTAMP_ISO(heure_pointage)
TIMESTAMPDIFF
(c 'DIFFERENCE')
C indique l'unité de mesure de l'écart que vous souhaitez obtenir
1 = fractions de s. 16 = jours
2 = secondes 32 = semaines
4 = minutes 64 = mois
8 = heures 128 = trimestres
  256 = Année

'DIFFERENCE' est la représentation caractères [ CHAR(22) ]
d'un écart entre deux timestamp.

TIMLESTAMPDIFF(32 ,
CAST(
CURRENT_TIMESTAMP
- CAST(DATLIV AS TIMESTAMP)
AS CHAR(22) )
)

indique l'écart en semaines
entre DATLIV et aujourd'hui
MIDNIGHT_SECONDS retourne le nbr de secondes qui sépare un timestamp de minuit
MIDNIGHT_SECONDS(pointage)


Quelques fonctions utiles EN RPG

 * calcul de la fin de mois
* astuce : pour le 17 Janvier, se positionner au 17 Février et enlever 17 jours

Dfindemois PI          D   
D Datein                      D   CONST

P Findemois       B               EXPORT
D                 PI          D
D Datein                      D   CONST

D Wdate S D

/free
wdate = Datein + %months(1);
wdate = wdate - %days( %subdt(wdate : *DAYS) ); 
return wdate;
/end-free
 * calcul du N° de semaine
* astuce : on part d'un dimanche connu (6 Janvier 80)
* on divise l'écart en jours, le reste EST le N° de jour dans la semaine
* sauf dimanche (= 0) ou on retourne 7.

Djoursemaine PI         1 0   
D Datein                      D   CONST

P joursemaine     B               EXPORT
D                 PI         1 0 
D Datein                      D   CONST

D Wdate S D

/free
nbdejours = %DIFF(wdate : D'1980-01-06' : *DAYS) ;
reste = %REM(nbdejours : 7);
if reste < 1; 
return reste + 7;
else;
return reste;
endif;
/end-free
 dsemaine          PR             2P 0
 d datein        D const

 psemaine     B                   export
 d                 pi             2P 0
 d datein                          D   const
 d                 DS                        
 d janvier4                        D   INZ(D'0001-01-04')         
 d  ANjanvier4                    4  0 OVERLAY(janvier4)          
 d Lundi           S               D                              
  /free                                                            
    // calcul du 4 janvier de l'année traitée                     
    ANjanvier4 = %SUBDT(DateIn : *Y);                             
    // calcul du Lundi précédent le 4 janvier                     
    Lundi = janvier4 - %DAYS(dayofweek(janvier4)-1) ;                                                                                
    // si date recue < au lundi ==> premier lundi,année précédente 
    if DateIn < Lundi;                                            
       ANjanvier4 -= 1;                                           
       Lundi = janvier4 - %DAYS(dayofweek(janvier4)+1);           
    endif;                                                        
    // nombre de semaine entières                                  
   return %DIV( %DIFF(DateIn:Lundi:*DAYS) : 7) +1;                
  /end-free                                                       


Dates ET DSPF

Les mots-clé DATFMT [éventuellement DATSEP] sont admis sur les écrans (depuis la V4R2)


A LA SAISIE :

- les séparateurs ne sont PAS obligatoires !

- les zéros [à gauche] non plus
     pour le 1er Février 2006 on admet avec DATFMT(*DMY) :  01/02/06
                                                010206
                                                10206
                                                1/2/06


-   on admet aussi DATFMT(*JOB) qui affiche (et accepte) une date au
    format du job en cours(*DMY en France), mais transmet TOUJOURS en *ISO
Enfin, un nouveau mot-clé MAPVAL est implémenté afin d'établir des conversions
     entre valeur affichée et valeur transmise au pgm.

     MAPVAL( (valeur-pgm1 valeur-écran1)
             (valeur-pgm2 valeur-écran2) ...)  jusqu'à 100 correspondances

     avec comme valeurs particulières :

          *BLANK on affiche que des blancs
          *CUR   valeur en cours (date en cours ou heure en cours)

exemple :        MAPVAL(('01/01/40' *BLANK))

                  si le pgm contient 01/01/40 j'affiche des blancs
             ET   si l'utilisateur entre des blancs j'envoi 01/01/40

DERNIERE MINUTE !
La PTF SI20165 contenue dans le dernier cumul de ptf (5298) modifie la structure interne des zones TIMESTAMP et ce faisant modifie le niveau de format des fichiers les contenant.

Il vous faut donc,
  • soit ne pas appliquer cette PTF (rappel SI20165)
  • soit passer les fichiers concernés en LVLCHK(*NO)
  • soit recompiler tous les programmes

La PTF SI21275 remplace la PTF en question et corrigerait le problème (à vérifier).

Copyright © 1995,2006 VOLUBIS