Bonjour à toutes et à tous.

Pour commencer, je ne suis pas un expert en sql et je débute a utiliser le PL SQl. Je me suis basé sur des tutoriels et des cours que j'ai pu trouver ici et la sur le net.
J'en suis à faire pleins d'essais mais la je bloque...

résumé :
Sur une table contenant un peu plus de 300 000 enregistrements, j'ai ajouté deux nouveaux champs (périmètre et surface).
Ensuite, j'ai créé deux triggers oracle permettant de mettre à jour automatiquement ces champs "périmètre" et "surface" lors d'ajout ou modification d'une donnée de la table.

J'ai donc besoin d'initialiser ces deux nouveaux champs sur l'ensemble des données existantes.
Pour cela j'ai voulu faire une requête sql toute simple du genre :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
update MaTable set FLT_PERIMETRE = '1' where OBJECTID is not null;
Cette requête fonctionne bien sur d'autres tables (plus petites) mais pas sur celle la... ou alors avec un nombre limité d'enregistrement

ça ça passe :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
update MaTable set FLT_PERIMETRE = '1' where OBJECTID < 3000;
Dès que je veux faire l'update sur un grand nombre de données de ma table, j'ai une erreur oracle

L'idée est de passer par PL SQL pour faire un Update par blocs de 1000 enregistrements.
Mais j'avoue j'ai trouvé pas mal de docs sur des sélections ou des updates simple mais j'ai du mal à adapter pour mes besoins.

Voici mon code actuel :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
SET ECHO ON
SET SERVEROUTPUT ON
 
declare
    compteur number;
 
     cursor Curseur(LeCompteur in number) is
              select  OBJECTID
             from (select  OBJECTID,ROWNUM AS NUMERO from Schema.MaTable where rownum < (LeCompteur+1)*1000)
             where NUMERO > 1000*LeCompteur AND  NUMERO < (LeCompteur+1)*1000 ;
 
begin
    compteur := 0;
 
    loop
            for Curs in Curseur(compteur)
            loop
 
            EXIT WHEN  Curs%NOTFOUND;
          update MaTable set FLT_SUPERFICIE = '1' where OBJECTID = Curs.OBJECTID;
 
          end loop;
 
            compteur := compteur + 1;
            EXIT WHEN compteur > 300;
     end loop;
 
end;

Mon problème :
Ce qui se passe c'est que ça mouline, et je ne vois pas pourquoi.

j'ai aussi essayé en utilisant une collection, ce qui me donne comme code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
declare
    compteur number;
 
          TYPE bat_array IS VARRAY(1000) OF MaTable%ROWTYPE;
          bats bat_array;
begin
    compteur := 0;
 
    loop
        bats := bat_array ();
 
        select  OBJECTID
        into :bats
        from (select  OBJECTID,ROWNUM AS NUMERO from Schema.MaTable where rownum < (compteur+1)*1000)
        where NUMERO > 1000*compteur AND  NUMERO < (compteur+1)*1000 ;
 
            for bat in bats()
            loop
            EXIT WHEN  Curseur%NOTFOUND;
          update MaTable set FLT_SUPERFICIE = '1' where OBJECTID = bat.OBJECTID;
 
          end loop;
 
         compteur := compteur + 1;
         Exit when compteur > 300;
 
     end loop;
 
end;
/
Mais j'ai une erreur lors du lancement : "not all variables bound" et je ne vois pas ce que j'ai mal fais.


Donc j'ai essentiellement (pour l'instant) deux requêtes à vous soumettre :
1 : Suis-je sur la bonne voie, ou je me complique la tache?

2 : un oeil (ou pleins) extérieur serait le bienvenue car les miens commencent à se croiser pour m'aider à corriger mes erreurs...

Merci d'avance.