IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PL/SQL Oracle Discussion :

Update par lots


Sujet :

PL/SQL Oracle

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 113
    Points : 58
    Points
    58
    Par défaut Update par lots
    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.

  2. #2
    En attente de confirmation mail
    Inscrit en
    Mars 2010
    Messages
    205
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 205
    Points : 230
    Points
    230
    Par défaut
    Tu devrais déjà nous montrer l'erreur oracle produite par l'update.

    Ensuite, un update d'une colonne sur 300 000 lignes, ça doit passer en quelques minutes, il y a peut-être un problème sur la base (configuration physique, paramètrage, activité tierce sur le serveur,...)

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 113
    Points : 58
    Points
    58
    Par défaut
    Bonjour Sgora,

    Voici l'erreur obtenue

    Error at line 1
    ORA-13050: unable to construct spatial object
    ORA-06512: at "MDSYS.SDO_3GL", line 784
    ORA-06512: at "MDSYS.SDO_GEOM", line 3115
    ORA-06512: at "Schema.Matable1_PERIM_TG", line 7
    ORA-04088: error during execution of trigger 'Schema.Matable1_PERIM_TG1_PERIM_TG'
    ORA-06512: at line 18
    Je précise que "Schema.Matable1_PERIM_TG" est le nom du trigger calculant le périmètre.

    Je continue de chercher de mon côté, j'ai trouvé ces deux liens qui peuvent être une piste mais je n'en suis pas sur... :
    passage de Oracle 8/9 vers Oracle 10
    http://www.developpez.net/forums/d43...on-geometries/
    Vérifier la validité des données de la table :
    http://database.itags.org/oracle/167934/

    Merci.

  4. #4
    En attente de confirmation mail
    Inscrit en
    Mars 2010
    Messages
    205
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 205
    Points : 230
    Points
    230
    Par défaut
    Ah, tu utilises l'option Spatial, c'est différent. Ne connaissant pas cette option très spéciale, je ne peux t'aider, mais ton problème vient sûrement de là.

    Voilà l'erreur telle qu'elle est dans la doc :

    ORA-13050 unable to construct spatial object

    Cause: This is an internal error.

    Action: Contact Oracle Support Services.
    Je ne saurais trop te conseiller de contacter le support Oracle.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 113
    Points : 58
    Points
    58
    Par défaut
    Citation Envoyé par sgora Voir le message
    Je ne saurais trop te conseiller de contacter le support Oracle.
    Héhé, j'ai bien voulu mais il faut avoir un identifiant associé a la licence oracle, que je n'ai pas, ce sont les dba de mon service informatique qui l'ont...
    J'avais bien trouvé ce message d'erreur ds la doc et demandé à un collègue dba s'il pouvait glaner des infos du support Oracle mais il n'a pas trouvé grand chose...

    je l'ai relancé la dessus, et s'il peut regarder aussi du côté du TableSpace de la table qui pose problème.

    C'est bizarre quand même que cela passe sur des tables qui ont 10 000 enregistrements mais que ça plante sur celle-ci au bout de seulement 4000 (environs), alors que j'utilise les mêmes requêtes et triggers...

    Merci quand même.

    Je suis toujours preneur de nouveaux conseils

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 32
    Points : 37
    Points
    37
    Par défaut
    Pour un update par lot, voir côté FORALL et BULK COLLECT .

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 113
    Points : 58
    Points
    58
    Par défaut
    Merci hdmea, je vais regarder ça.

Discussions similaires

  1. Update par date immédiatement inférieur
    Par MOLLET dans le forum Langage SQL
    Réponses: 1
    Dernier message: 09/11/2005, 19h05
  2. insertions par lots
    Par boubilescu dans le forum Access
    Réponses: 1
    Dernier message: 04/11/2005, 10h32
  3. [Mail] newsletter, envoi de mail par lot
    Par jexl dans le forum Langage
    Réponses: 9
    Dernier message: 08/09/2005, 16h44
  4. Outil pour modification de fichiers html par lots
    Par Tavernier dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 19/08/2005, 09h21
  5. [sybase] Suppression de tables par lot
    Par Higgins dans le forum Sybase
    Réponses: 2
    Dernier message: 30/09/2004, 16h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo