Quelle est la définition d'un index ?

RPG (3 et 4, free), CL, SQL, etc...
Répondre
germor
Messages : 75
Enregistré le : lun. 06 juin 2011, 08:01:43

Quelle est la définition d'un index ?

Message par germor »

Bonjour,

Besoin d'un petit rafraichissement sur la définition d'un index :

Une table : TABLE contient les champs CHAMP_1, CHAMP_2, CHAMP_3.
Cette table a une contrainte de clé primaire sur le CHAMP_1.

Un index : TABLEI01 sur cette table contient les champs : CHAMP_2 et CHAMP_3.

Dans un programme RPGLE, l'index TABLEI01 est déclaré.

Code : Tout sélectionner

     FTABLEI01UF A E           K Disk    Rename(TABLE:TABLEF1)
     F                                     Commit                        
Un format est préparé avec comme valeurs :
dans CHAMP_1 une valeur auto-incrémentée (donc nouvelle),
dans CHAMP_2 et CHAMP_3 des valeurs déjà existantes (c'est à dire que le couple CHAMP_1 et CHAMP_2 existe déjà)

Lors d'un WRITE de l'index TABLEI01 le systeme positionne un indicateur de tentative d'écriture en double.

Code : Tout sélectionner

...
     C                   Write     TABLEF1                            50
      * clé en double
     C   50              Eval      P_Retour = '02'   
...
Ma question est :
le WRITE de l'index écrit bien toutes les colonnes de la table,
ne tient pas compte de la contrainte de clé primaire de la table,
considère les champs de l'index comme des clés primaires.

Pour faire un WRITE de mon format, faut il déclarer la table dans le RPGLE ou existe t'il un autre moyen ?

cmasse
Site Admin
Messages : 779
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

index, réponse

Message par cmasse »

Bonjour,
le WRITE de l'index écrit bien toutes les colonnes de la table,
Ca dépend
1/ si l'index est un logique, voir la liste des zones du format de l'index
2/ si l'index est un index SQL, depusi la V6 on peut aussi préciser la liste des zones

Mais j'avais cru comprendre que le WRITE se faisait dans la table
ne tient pas compte de la contrainte de clé primaire de la table,
bien sur que SI ! c'est le but du jeu, que le contrôle ne puisse être contourné !
considère les champs de l'index comme des clés primaires.
non, non ! ne sont considérés comme des clés primaires ..... que les clés primaires.

ceci dit les INDEX avec Unicité (mot clé UNIQUE) provoquent aussi une erreur de clé en double sans être des clés primaires.


SI vous DUMPER, avez vous dans CHAMP_1 une valeur déjà existante dans la base ?
Christian Massé (Volubis.fr)

germor
Messages : 75
Enregistré le : lun. 06 juin 2011, 08:01:43

(sans texte)

Message par germor »

Bonjour,
L'index est un LF qui contient bien tous les champs de la table
Info fichier
Fichier . . . . . . . . . . . . . . . . . . : TABLEI01
Bibliothèque . . . . . . . . . . . . . . : BIBLIOTHEQUE
Emplacement du fichier . . . . . . . . . . : *LCL
Description externe . . . . . . . . . . . . : Oui
Nombre de formats . . . . . . . . . . . . . : 1
Type de fichier . . . . . . . . . . . . . . : Logique
Type de fichier SQL . . . . . . . . . . . . : INDEX
son source est :

Code : Tout sélectionner

create index TABLEI01 on TABLE (CHAMP_2 asc, CHAMP_3 asc);  
Et le WRITE se fait sur le format
ce format (TABLEF1) dans la carte F renomme le format TABLE, et est lié à TABLEI01

Le DSPFD de l'index est
Description du chemin d'accès
Maintenance du chemin d'accès . . . . . . . : MAINT *IMMED
Valeurs de clé unique obligatoires . . . . : UNIQUE Non
Ordre des clés . . . . . . . . . . . . . . : Non indiqué
Sélection/omission indiquée . . . . . . . . : Non
Chemin d'accès journalisé . . . . . . . . . : Non
Type de chemin d'accès . . . . . . . . . . : Par clé
Nombre de zones clés . . . . . . . . . . . : 2
Format d'enregistrement . . . . . . . . . . : TABLE
Zone clé . . . . . . . . . . . . . . . . : CHAMP_2
Séquence . . . . . . . . . . . . . . . : Croissante
Signe indiqué . . . . . . . . . . . . . : NON SIGNE
Hors texte/Digit indiqué . . . . . . . : *NONE
Séquence alternée . . . . . . . . . . . : Non
Zone clé . . . . . . . . . . . . . . . . : CHAMP_3
Séquence . . . . . . . . . . . . . . . : Croissante
Signe indiqué . . . . . . . . . . . . . : NON SIGNE
Hors texte/Digit indiqué . . . . . . . : *NONE
Séquence alternée . . . . . . . . . . . : Non
Je n'ai pas dumpé mais dans le débogueur, à l'instruction qui précède le WRITE, j'ai dans CHAMP_1 une valeur qui n'existe pas dans la TABLE (vérifié par sql).

EL MANSSOURI
Messages : 13
Enregistré le : jeu. 03 déc. 2009, 17:13:03

(sans texte)

Message par EL MANSSOURI »

Bonjour,

S'assurer qu'aucun autre logique ou index avec clé unique sur un, deux ou les trois champs n'existe sur le fichier TABLE (DSPDBR) .

cmasse
Site Admin
Messages : 779
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

clé en double : message d'erreur

Message par cmasse »

Alors vous devez avoir un message dans la JOBLOG lors de la tentative de clé en double

Code : Tout sélectionner

                     Complément d'informations sur message                      
                                                                                
 ID message . . . . . . :   CPF5009                                             
 Date d'envoi . . . . . :   29/05/13      Heure d'envoi  . . . . :   15:51:34   
                                                                                
 Message . . . . :   Clé d'enregistrement en double dans le membre VINS.        
                                                                                
 Cause . . . . . :   L'opération d'écriture ou de mise à jour dans le membre    
   numéro 1 (enregistrement numéro 0, format VINS) pour le membre VINS du       
   fichier VINS, se trouvant dans BDVIN1, n'a pas abouti. Le membre numéro 1    
   (enregistrement numéro 709, format VINS) a la même clé d'enregistrement que  
   le membre numéro 1 (enregistrement numéro 0, format VINS).  Si ce numéro     
   d'enregistrement est 0, la clé d'enregistrement en double a été créée lors   
   d'une opération d'écriture.                                                  
 Que faire . . . :   Modifiez les clés en double, de sorte que chaque           
   enregistrement ait une clé unique. Renouvelez votre demande. 
Vous remarquerez que dans le message vous avez le nom du fichier et le n° de record permettant de connaitre la valeur existante.
Christian Massé (Volubis.fr)

germor
Messages : 75
Enregistré le : lun. 06 juin 2011, 08:01:43

(sans texte)

Message par germor »

Je n'ai pas d'autre index unique qui pointe sur les champs de TABLE.
*** enfin si :oops: c'est que en vrai ma TABLE contient 17 champs, et j'ai un index TABLEI02 unique qui pointe sur les champs 11 et 12.
Donc je vais vérifier si cet unique de l'index TABLEI02 est bien nécessaire.

Pour ma log je dois attendre demain après livraison arcad en environnement de test.

merci pour vos réponses :wink:

germor
Messages : 75
Enregistré le : lun. 06 juin 2011, 08:01:43

(sans texte)

Message par germor »

Bonjour :wink:

Le message d'erreur dans mon historique de travail est :

Code : Tout sélectionner

ID message . . . . . . :   CPF502E                                            
Date d'envoi . . . . . :   11/06/13      Heure d'envoi  . . . . :   09:48:24                                                                          
Message . . . . :   Les contraintes référentielles n'ont pas pu être validées 
  pour le membre TABLEI01.                                                  
Cause . . . . . :   L'opération en cours sur le membre TABLEI01, fichier    
  TABLEI01, bibliothèque BIBLITEST a échoué. La contrainte TABLE2_TABLE 
  pour le fichier dépendant TABLE dans la bibliothèque BIBLITEST et pour le
  fichier parent TABLE2 dans la bibliothèque BIBLITEST n'a pas pu être      
  validée. Le numéro d'enregistrement 375855 dans le membre TABLE2, fichier  
  TABLE2, bibliothèque BIBLITEST, a été verrouillé par le travail           
  904515/QUSER/QZDASOINIT. Si le numéro d'enregistrement est 0, le fichier    
  TABLE2 de la bibliothèque BIBLITEST est verrouillé par le travail         
  904515/QUSER/QZDASOINIT. Le nom du travail n'est pas disponible s'il a la   
   valeur *N.                                                                
 Que faire . . . :   Renouvelez votre demande lorsque l'enregistrement ou le 
   fichier n'est plus verrouillé.                                            
La contrainte de TABLE vers TABLE2 est :

Code : Tout sélectionner

alter table TABLE                                         
    foreign key TABLE2_TABLE (CHAMP_2)                
       references TABLE2 (CHAMP_1) on delete restrict   
                                   on update no action; 
l'index TABLEI01 n'est pas "unique index".
En debut du programme PROGR1, je recherche l'enregistrement parent dans TABLE2 par un appel à un programme de service PROGR3 qui contient entre autres :

Code : Tout sélectionner

 FTABLE2I01IF    E           K Disk    Rename(TABLE2:TABLE201F) 
...
     C     KTABLE2       Chain     TABLE2I01F    
En début de mon programme de service PROGR1 :
Si l'enregistrement parent est trouvé je prépare puis je fais le write de TABLE, qui me pose prb.
Si l'enregistrement parent n'est pas trouvé, l'enregistrement parent dans TABLE2 est créé,
par un CallP à un autre programme de service PROGR2.

Dans PROGR2 le fichier TABLE2 est déclaré, ouvert, écrit et fermé :

Code : Tout sélectionner

     FTABLE2    O    E             Disk    Rename(TABLE2:TABLE2F) Commit
     F                                     UsrOpn                                  
...
     C                   If        Not %Open(TABLE2)                            >1
     C                   Open      TABLE2
     C                   EndIf                                                  <1  
...
     C                   Write     TABLE2F  
...
     C                   If        %Open&#40;TABLE2&#41;                               >1
     C                   Close     TABLE2
     C                   EndIf                                                  <1     
puis j'appelle à nouveau PROGR3 pour rechercher l'enregistrement parent dans TABLE2 :

Code : Tout sélectionner

 FTABLE2I01IF    E           K Disk    Rename&#40;TABLE2&#58;TABLE201F&#41; 
...
     C     KTABLE2       Chain     TABLE2I01F    
juste avant le write dans PROGR1:

Code : Tout sélectionner

...
     C                   Write     TABLEF1                            50
      * clé en double
     C   50              Eval      P_Retour = '02'   
...
Au debogueur dans PROGR1, l'enregistrement CHAMP_2 est préparé pour écrire dans TABLE avec dans CHAMP_2 la même valeur que dans son parent de TABLE2.

Dans STRSQL, l'enregistrement numéro 375855 de TABLE2 est bien créé avec dans CHAMP_1 la même valeur que dans son enfant de TABLE.

J'ai aussi cette erreur

Code : Tout sélectionner

 ID message . . . . . . &#58;   CPF4028                                             
Date d'envoi . . . . . &#58;   11/06/13      Heure d'envoi  . . . . &#58;   13&#58;34&#58;40   
Message . . . . &#58;   Ouverture du membre TABLE2 changée en SEQONLY&#40;*NO&#41;.       
Cause . . . . . &#58;   Le membre TABLE2, TABLE2, BIBLITEST a été ouvert avec   
  SEQONLY&#40;*YES&#41; dans le pgm ou dans la commande OVRDBF. Or, ce paramètre a été 
  remplacé par SEQONLY&#40;*NO&#41; en raison de l'erreur 1.                           
    1 - Le programme a ouvert le membre TABLE2 en écriture seule.             
  SEQONLY&#40;*YES&#41; était défini avec le nombre d'enreg par défaut. Ce paramètre a 
  été remplacé par SEQONLY&#40;*NO&#41; afin de permettre au programme de gérer les    
  clés en double, le mappage de données, le mappage de clés et les erreurs de  
  sélection et/ou d'omission lors de l'écriture.                               
  Que faire &#58; Erreur 1 ou 6 &#58;                                                   
    -- Si le remplacement du paramètre SEQONLY&#40;*YES&#41; par SEQONLY&#40;*NO&#41; n'est   
  pas accepté, remplacez-le en indiquant SEQONLY&#40;*YES N&#41; dans la commande     
  OVRDB, N spécifiant le nombre d'enregistrements.  Renouvelez votre demande. 
  
Je ne vois pas dans le code où changer ce paramêtre.

Quelqu'un pourrait il m'éclairer du pourquoi un enregistrement reste locké alors que le fichier a été fermé ?

cmasse
Site Admin
Messages : 779
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

(sans texte)

Message par cmasse »

le verrouillage a été posé par le travail 904515/QUSER/QZDASOINIT.

Vous travaillez avec JDBC ? avec quel niveau d'isolation ?

Votre RPG est une procédure stockée ?


merci de vos réponses
Christian Massé (Volubis.fr)

germor
Messages : 75
Enregistré le : lun. 06 juin 2011, 08:01:43

(sans texte)

Message par germor »

merci :wink:

Un traitement JDBC, qui appelle une procédure stockée, crée l'enregistrement Parent et le verrouille dans son niveau d'isolation.

Ensuite un programme de service appelle une autre procédure stockée qui essaie de créer un enregistrement Enfant.
Il existe une contrainte qui référence l'Enfant sur le Parent, et le Parent est verrouillé, donc l'Enfant n'est pas créé.

J'ai clarifié mon traitement JDBC et maintenant la création marche.

Le niveau d'isolation est :

Code : Tout sélectionner

Travail&#58;   QZDASOINIT     Util&#58;   QUSER          Numéro&#58;   904515        
                                                                         
Unité exécut  . . . . . . . . . . &#58;   *NONE                              
ID unité d'oeuvre logique . . . . &#58;   APPN.MACHINE.X'206FABB7DB7F'.00002
ID verrouillage espace  . . . . . &#58;   UDB_010000000014FDB3               
Définition de validation  . . . . &#58;   *DFTACTGRP                         
Groupe d'activation . . . . . . . &#58;   2                                  
Groupe ASP  . . . . . . . . . . . &#58;   *SYSBAS                            
                                                                         
Emplacement des ressources  . . . &#58;   LOCAL                              
Niveau de verrouillage par défaut &#58;   *CS                                
Rôle  . . . . . . . . . . . . . . &#58;                                      
Etat  . . . . . . . . . . . . . . &#58;   REINITIALISATION                   
  Date/horodatage . . . . . . . . &#58;                                      
Resynchronisation en cours  . . . &#58;   NON                                
Opération heuristique . . . . . . &#58;                                      
la transaction globale du JDBC

Code : Tout sélectionner

   // niveau &#58; java.sql.Connection.TRANSACTION_READ_UNCOMMITTED

Répondre