-- corr_table_2020.sql
-- 13 avril 2021
----------------------------------------------------------------------------------------
-- 6.3.1 : le probleme : 

-- un programme correct : 
create or replace procedure traitement2(
    l_idc client.idc%type,
    la_ville village.ville%type,
    le_jour sejour.jour%type,
    l_idv out village.idv%type,
    l_ids out sejour.ids%type,
    l_activite out village.activite%type)   
is
    cursor c is
        select idv, prix, activite 
            from village 
            where ville = la_ville
            order by prix desc;
    le_prix village.prix%type;
begin
    open c;
    fetch c into l_idv, le_prix, l_activite;
    if c%found then
        l_ids := seq_sejour.nextval; 
        insert into sejour 
            values(l_ids, l_idc, l_idv, le_jour);
        update client 
            set avoir = avoir - le_prix
            where idc = l_idc;
    else
        l_idv := -1;
	l_ids := -1;
	l_activite := 'neant';
    end if;
end;
/

-- une reorganisation SPI :
-- remplacer la table village
-- (1, Rio, kitesurf, 10, 25)
-- (2, Rio, sieste, 5, 250)
-- en :
-- activ(idv, prix, activite)
-- (1, 10, kitesurf)
-- (2, 5, sieste)
-- et :
-- lieu(idv, ville, capacite)
-- (1, Rio, 25)
-- (2, Rio, 250)
-- est une reorganisation ? oui
-- SPI ? oui

-- remarque : renommer village en village2 : est une reorganisation SPI

-- un appel du (meme) programme terminant en erreur apres la reorganisation :
-- il termine en erreur ? oui : -942 : la table village n'existe pas

-- bref ce code est parfait logiquement mais "n'est pas robuste pour l'independance"

declare
    iv village.idv%type;
    l_ids sejour.ids%type;
    a village.activite%type;
begin
    traitement2(1, 'Chatelaillon', 361, iv, l_ids, a);
    dbms_output.put_line('idv '||iv||', ids '||l_ids||', activite '||a);
end;
/

-- 6.3.2 : corrigez l'appli pour que ce code soit en plus robuste aux problemes
-- d'independance des niveaux

-- ???...

Une fois le problème existant il est trop tard.
Donc, il faut le gérer en amont, lors de la création de l application, comme suit.

A l origine, écrire une appli "correcte".
1. créer les tables : village
2. créer une vue par table : vue_village = select * from village
3. coder les procédures PL/SQL SUR LES VUES :

create or replace procedure traitement2 ... is
    cursor c is
        select idv, prix, activite
            from vue_village
            where ville = la_ville
            order by prix desc;
...
begin
    open c;
...


Au moment de la réorganisation :

4. bloquer la base
4bis. réorganiser :
remplacer la table village par activ(idv, prix, activite) et lieu(idv, ville, capacite)

5. rédéfinir la vue (pour chaque table) vue_village POUR QUE elle contienne
toujours la meme chose :
create or replace vue_village as
    select activ.idv, ville, activite, prix, capacite
      from activ, lieu
      where activ.idv = lieu.idv

: vue_village contient exactement l ancienne table village.

5bis. débloquer la base

declare
    iv village.idv%type;
    l_ids sejour.ids%type;
    a village.activite%type;
begin
    traitement2(1, 'Chatelaillon', 361, iv, l_ids, a);
    dbms_output.put_line('idv '||iv||', ids '||l_ids||', activite '||a);
end;
/

: cet appel donne exactement le même résultat que sur la base avant réorganisation. 

----------------------------------------------------------------------------------------
