Nouveautés SQL en V5R20

BoTTom |    Changer de couleur
 
 nouveautés SQL en V5R20 :
 
 - variables de type ROWID, permettant une génération automatique de clé
 
 
 - fonction SQL, retournant une table et utilisable dans la clause FROM
 
   (en fait la fonction retourne une ligne à la fois)
 
 
 - Notion de TABLE TEMPORAIRE  (DECLARE GLOBAL TEMPORARY TABLE)
 
 
 - DIVERS : UNION admis dans le vues, ORDER BY sur des colonnes non choisies
 
 
 - SAVEPOINT (ou point de reprise) permettant un retour arrière ROLLBACK,
     avec choix du point du "moment" logique de reprise.
 
 
 


|    Changer de couleur
 
 - clé générée automatiquement, deux syntaxes :
 
 
   > dans les deux cas on peut préciser :
 
                  --ALWAYS--------      toujours
     GENERATED ---                --->
                  -- BY DEFAULT---      uniquement si la zone est nulle
 
 
   A/ ROWID. Il s'agit de variable VARCHAR(40) contenant des valeur générées
              de manière non consécutive.
 
      Create TABLE test1 (ID ROWID GENERATED ALWAYS ,
                          LIB CHAR(40), DATCRT DATE)
 
 
   B/ AS IDENTITY , est associé à un champ numérique sans décimale,
 
      Create TABLE test1 (ID INTEGER AS IDENTITY START WITH 100,
                          LIB CHAR(40), DATCRT DATE)


|    Changer de couleur
 
      on peut alors préciser avec AS IDENTITY :
 
      --START WITH (valeur initiale)----------------->
 
      >-INCREMENT BY (incrément)---------------------->
 
          --MINVALUE (valeur mini) -
      >--                           ----------------->
          --NO MINVALUE ---------- -
 
         --MAXVALUE (valeur maxi) -
      >--                           ----------------->
         --NO MAXVALUE ---------- -
 
         -- CYCLE----------    ---ORDER-------
      >--                  ----               ------->
         --NO CYCLE--------    --- NO ORDER---
 
   avec CYCLE, quand MAXVALUE est atteint on recommence à MINVALUE.
   NO ORDER indique une numérotation qui peut ne pas être réalisée dans
    l'ordre  des requêtes.


|    Changer de couleur
 et enfin :
 
        -- CACHE x ----                  indique que DB2/400 peut garder
   >----               -------------- .   en mémoire les x dernières valeurs
        --NO CACHE----                    (plus rapide)
 
 
 AS IDENTITY est un attribut d'un champ numérique
 
 ROWID est un nouveau type de champ (à déclarer en RPG par SQLTYPE(ROWID).)
 
 Exemple :
 
 CREATE TABLE TABCDE
     (CDENO SMALLINT NOT NULL
        GENERATED ALWAYS AS IDENTITY
                           (START WITH 500
                            INCREMENT BY 1
                            CYCLE),
      LIVREA VARCHAR (36) ,
      CDEDAT DATE)
 


|    Changer de couleur
 
 les ordres INSERT et UPDATE sont completés comme suit :
 
    UPDATE nom-table ----------------------------------SET ...  -->
                       |                          |
                       |-OVERRIDING SYSTEM VALUE--|
                       |                          |
                       |-OVERRIDING USER VALUE----|
 
     Avec OVERRIDING SYSTEM VALUE, on peut modifier une colonne ROWID ou
           AS IDENTITY définie avec GENERATED ALWAYS.
 
     Avec OVERRIDING USER VALUE, on peut modifier une colonne définie avec
           GENERATED ALWAYS ou GENERATED BY DEFAULT.
 
     sans indication la clause SET ne peut PAS manipuler une clé générée
      avec la clause GENERATED ALWAYS, mais on peut manipuler
       une zone AS IDENTITY GENERATED BY DEFAULT.
 
     Par contre, une zone de type ROWID avec GENERATED BY DEFAULT,
        uniquement si la nouvelle valeur a elle même été génerée par DB2.
        (copie de fichier, par exemple)


|    Changer de couleur
 
 - création de table par référence :
 
   en V5R10 CREATE TABLE admet la clause like
 
     si vous souhaitez dupliquer aussi la clause IDENTITY, il faut indiquer
 
      CREATE TABLE CLITEMP LIKE CLIENTS INCLUDING IDENTITY 
 
   SQL admet, en plus, en V5R20 la syntaxe suivante, permettant
        une duplication partielle de la liste des zones [du format] :
 
 
      CREATE TABLE nom-fichier AS (sous-sélection)
            WITH [NO] DATA [INCLUDING IDENTITY]
 
     avec WITH DATA, la table est créé et les données dupliquées.
 
  Exemple :
 
    CREATE TABLE CLITMP AS (SELECT nomcli, adr1, adr2, dept, ville from cli)
            WITH NO DATA


|    Changer de couleur
 
 - tables temporaires  :
 
   DECLARE GLOBAL TEMPORARY TABLE (même syntaxe que CREATE TABLE) -->
 
                   --DELETE ROWS---             --DELETE ROWS---
    >-- ON COMMIT--                -- ON DELETE                 ---->
                   -PRESERVE ROWS--             - PRESERVE ROWS-
 
 
    >---------------------------------------
       |                |   |             |
       |--WITH REPLACE--|   |--NOT LOGGED-|
 
 
    créé une table dans QTEMP (peut être qualifiée aussi par "SESSION")
 
    WITH REPLACE permet une création avec remplacement, si la table existe
     déja dans QTEMP
 
    NOT LOGGED, indique une table non journalisée (insensible aux ROLLBACK)
 


|    Changer de couleur
 
Exemples :
 
 DECLARE GLOBAL TEMPORARY TABLE CLIENTS
         (nocli integer, raisoc char(50),
           adr1 varchar(50) , ville varCHAR(50) )
  WITH REPLACE
 
 
 DECLARE GLOBAL TEMPORARY TABLE CLITEMP AS
         (SELECT nocli , raisoc, adr1 , ville
            from clients) WITH DATA
 
Dans tous les cas de figure, la table n'apparait pas dans les catalogues SQL
                                et est détruite en fin de session.
 
- SAVEPOINT
 
 Cette notion permet de matérialiser des étapes dans une transaction
  offrant la possibilité de revenir à une étape précise et non au début
  de la transaction en cas de ROLLBACK.
 


|    Changer de couleur
 
 un point de reprise est posé par l'instruction SAVEPOINT (un SEUL AS/400)
 
      UPDATE client ...                       ;
 
    SAVEPOINT MAJ ON ROLLBACK RETAIN CURSORS  ;
 
      DELETE FROM CLIENTS ...  ;
      DELETE FROm COMMANDES    ;
 
    SAVEPOINT DLT ON ROLLBACK RETAIN CURSORS   ;
 
      INSERT INTO ...          ;
 
    IF xxx ROLLBACK TO SAVEPOINT MAJ
     ELSE RELEASE SAVEPOINT ;
 
 ON ROLLBACK RETAIN CURSORS, permet de garder le(les) curseur(s) ouverts
 ON ROLLBACK RETAIN LOCKS , permet de garder les verrouillages/ligne
 
 RELEASE SAVEPOINT, libère (détruit) le point de reprise
 


|    Changer de couleur
 
Fonction retournant une table.
 
Vous pouvez écrire une fonction (PL/SQL ou RPG) retournant une table.
 
 il s'agit en fait d'un programme retournant des données non Base de données
 (une ligne à la fois), permettant d'utiliser avec SQL des informations
 externes (fichiers IFS, fichier en interne, XML, ...)
 
 la fonction est appellée une fois pour initialiser le dialogue
 puis une fois par ligne à retourner, et enfin une ultime fois à la fin.
 
 CREATE FUNCTION nom-fonction ( [param1 [,param2 ..]] )
   RETURNS TABLE (zone1 char(50), zone2 dec(7, 2) ....)
 
 la fonction est utilisée ensuite directement dans la clause FROM, par :
 
 SELECT zone1 from TABLE( nom-fonction(paramètre) )
 
 
    une jointure est possible
 


|    Changer de couleur
 
- Toutes les fonctions acceptent un nouveau paramètre :
 
     FENCED , la fonction s'exécute dans un thread à part
 
              (plus sûr, plus gourmand en ressources)
 
     NOT FENCED , le contraire.
 
 
- HOLD LOCATOR nom-variable.
 
  pour les variables contenant un pointeur sur un champ BLOB (ou CLOB),
   le pointeur reste valide après la transaction (COMMIT).
 
- UNION admis dans le CREATE VIEW
 
 
    CREATE VIEW v1 AS SELECT * FROM FACTURES
                       UNION
                      SELECT * FROM ARCHIVES
 


|    Changer de couleur
 
- les expressions utilisées dans ORDER BY, n'ont plus à être présentes dans
   la liste des colonnes du SELECT.
 
 
- notion de CURRENT SCHEMA
 
   contient la base de données à utiliser pour les ordres non qualifiés
 
   à l'origine : USER (l'utilisateur en cours) en dénomination *SQL
                 *LIBL en système de dénomination *SYS (système)
 
   modifiable maintenant par SET SCHEMA
 
 
   SET ----------------SCHEMA-----------------------------------------
        |          |             |           |
        |-CURRENT--|             |--un-nom---|
                                 |           |
                                 |--DEFAULT--|
                                 |           |
                                 |--USER-----|


|    Changer de couleur
 
 Et enfin les limites V5R10 quant aux sous-requêtes SQL disparaissent
 
 soit un fichier des producteurs (de vin)
 et un fichier des vins (contenant le code producteur)
 
 nous pouvons demander la requête suivante :
 
 SELECT P.pr_code, pr_nom, appel_code, count(*)
 FROM bdvin/producteurs P join bdvin/vins V
  on P.pr_code = V.pr_code
 GROUP BY P.pr_code, pr_nom, appel_code
 
 ensuite mémorisons cet ordre dans une vue
 
 CREATE VIEW BDVIN/stat as
  SELECT P.pr_code, pr_nom, appel_code, count(*) AS NBRVINS
  FROM bdvin/producteurs P join bdvin/vins V
   on P.pr_code = V.pr_code
  GROUP BY P.pr_code, pr_nom, appel_code
 
 


|    Changer de couleur
 Nous pouvons maintenant demander a voir sur chaque ligne le nombre de vins
  du producteur et le nombre de vins de l'appellation(tous producteurs)
 
  SELECT pr_nom, nbrvins,
  (select sum(nbrvins)
    from stat where appel_code = S.APPEL_CODE) as total_appel
  from stat S
 
 ce qui nous affiche :
  ..............................................................
  : PR_NOM                           NBRVINS     TOTAL_APPEL   :
  : Château Marquis de Terme               1              54   :
  : Château Maucaillou                     3               9   :
  : Château Mayne Lalande                  2              23   :
  : Château Monbrison                      1              54   :
  : Château Moulin La Pitié                1              11   :
  :............................................................:
 
 Nous pouvons même maintenant aller jusqu'à demander un % sur chaque ligne
  avec la requête suivante :
 
 


|    Changer de couleur
SELECT pr_nom, nbrvins,
(select sum(nbrvins)
  from stat where appel_code = S.appel_code) as total_appel   ,
(select dec(s.nbrvins, 7 , 3) / dec(sum(nbrvins), 7 , 3) * 100
  from stat where appel_code = S.appel_code) as pourcentage
from stat S
 
ce qui nous affiche :
...........................................................................
: PR_NOM                      NBRVINS     TOTAL_APPEL       POURCENTAGE   :
: Château Marquis de T              1              54           1,851     :
: Château Maucaillou                3               9          33,333     :
: Château Mayne Laland              2              23           8,695     :
:.........................................................................:
permettant, pour terminer, un classement par % (des 10 premiers par ex.)
 
 SELECT pr_nom, nbrvins,
 (select sum(nbrvins)
   from stat where appel_code = S.appel_code) as total_appel   ,
 (select dec(s.nbrvins, 7 , 3) / dec(sum(nbrvins), 7 , 3) * 100
   from stat where appel_code = S.appel_code) as pourcentage
 from stat S ORDER BY 4 DESC FETCH FIRST 10 ROWS ONLY 





©AF400