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 :
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 :
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 :
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 :
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.
Partager