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

Oracle Discussion :

[PL/SQL][CURSEUR]invalid ROWID!!!


Sujet :

Oracle

  1. #1
    Membre du Club Avatar de thief
    Inscrit en
    Décembre 2003
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 93
    Points : 47
    Points
    47
    Par défaut [PL/SQL][CURSEUR]invalid ROWID!!!
    Bonjour tous !
    j'ai des pbs avec des curseurs! j'explique: j'essaie de mettre à jour les valeurs d'une table avec les valeurs recuperées d'une autre autre table alors pour cela je fais comme suit:
    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
     
    CREATE OR REPLACE PROCEDURE UPDATE_BILL
    IS
     
    TYPE CALL_REC IS RECORD(id NUMBER,msis CHAR(20),tp CHAR(3), mnt NUMBER);
    call CALL_REC;
    mont NUMBER;
    CURSOR c1 IS SELECT ID,MSISDN,TYPE,MONTANT FROM CALL_I20050801RESUME;
    CURSOR c2(id IN CALL_I20050801RESUME.ID%TYPE, msi IN CALL_I20050801RESUME.MSISDN%TYPE, 
             typ IN CALL_I20050801RESUME.TYPE%TYPE)IS
       SELECT CHARGE FROM BILL_I20050801 WHERE SUBSCRIBER_ID=id AND TRIM(HANDSET)=TRIM(msi)
          AND TRIM(CHASERV)=TRIM(typ) FOR UPDATE;
    BEGIN
     
       OPEN c1;
          LOOP
             FETCH c1 INTO call;
             EXIT WHEN c1%NOTFOUND;
             OPEN c2(call.id,call.msis,call.tp);
                FETCH c2 INTO mont;
                UPDATE BILL_I20050801 SET CHARGE=call.mnt WHERE CURRENT OF C2;
             CLOSE c2;
          END LOOP;
       CLOSE c1;
     
    END;
    Après execution j'ai ce message d'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ERREUR à la ligne 1 :
    ORA-01410: invalid ROWID
    ORA-06512: at "UPDATE_BILL", line 20
    ORA-06512: at line 1
    j'ai passé tout le week end la dessus!
    Merci pour votre aide d'avance!

  2. #2
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    j'ai trouvé une note : http://metalink.oracle.com/metalink/plsql/ml2_documents.showDocument?p_database_id=NOT&p_id=18815.1

    This error is raised when an operation refers to a ROWID in a table for which there is no such row.

    The reference to a ROWID may be implicit from a WHERE CURRENT OF clause or directly from a WHERE ROWID=... clause.

    ORA 1410 indicates the ROWID is for a BLOCK that is not part of this
    table. If you update a rowid where the BLOCK is valid but the slot
    within the block is invalid you just get ZERO rows processed/returned.
    This can be a source of confusion as it is inconsistent.

    If you have a cursor that selects from more than one table and
    has 'for update' at the end - and then you are trying to do delete/
    update WHERE CURRENT OF <cursor_name>, then change the 'for update' to 'for update OF <column_on_table_that doing_dml_on>' -
    see Bug 502671 (Closed - not a bug.)
    Essaye :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CURSOR c2(id IN CALL_I20050801RESUME.ID%TYPE, msi IN CALL_I20050801RESUME.MSISDN%TYPE,
             typ IN CALL_I20050801RESUME.TYPE%TYPE)IS
       SELECT CHARGE FROM BILL_I20050801 WHERE SUBSCRIBER_ID=id AND TRIM(HANDSET)=TRIM(msi)
          AND TRIM(CHASERV)=TRIM(typ) FOR UPDATE OF CHARGE;

  3. #3
    Membre émérite Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Points : 2 370
    Points
    2 370
    Par défaut
    Comme ça à l'oeil je dirais que tu devrais essayer de ramener toutes les colonnes dans C2.

    A mon avis pour faire WHERE CURRENT OF, il a besoin des ROWID et je ne suis pas sûr qu'il les ramène dans ton curseur C2. En même temps ça me paraît pas logique... donc je sais pas trop. Et en évitant le WHERE CURRENT OF ?

  4. #4
    Membre du Club Avatar de thief
    Inscrit en
    Décembre 2003
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 93
    Points : 47
    Points
    47
    Par défaut
    orafrance
    J'ai essayé ta proposition mais la meme erreur!!
    je desespère un peu!

  5. #5
    Rédacteur

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 320
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 320
    Points : 3 798
    Points
    3 798
    Par défaut
    Est ce que tu analyse tes objets fréquemment , reconstruire les index ?

  6. #6
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    t'es sûr que la ligne existe pour les paramétres que tu mets ? Tu serais bien inspirer d'ajouter un test

  7. #7
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut FETCH vs FOR
    Je ne sais pas si ça diffère, mais essaye avec des FOR IN plutôt qu'avec des FETCH
    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
    CREATE OR REPLACE PROCEDURE UPDATE_BILL 
    IS 
    CURSOR c1 IS SELECT ID,MSISDN,TYPE,MONTANT FROM CALL_I20050801RESUME; 
    CURSOR c2(ID IN CALL_I20050801RESUME.ID%TYPE, msi IN CALL_I20050801RESUME.MSISDN%TYPE, 
             typ IN CALL_I20050801RESUME.TYPE%TYPE)IS 
       	SELECT CHARGE 
    	FROM BILL_I20050801 
    	WHERE SUBSCRIBER_ID = ID 
    	AND TRIM(HANDSET) = TRIM(msi) 
        AND TRIM(CHASERV) = TRIM(typ) 
    	FOR UPDATE; 
    BEGIN 
       FOR r1 IN c1 
       LOOP 
          FOR r2 IN c2(r1.ID, r1.msis, r1.tp) 
          LOOP
             UPDATE BILL_I20050801 
    			SET CHARGE=r1.montant 
    			WHERE CURRENT OF c2; 
    	  END LOOP; 
       END LOOP; 
    END;

  8. #8
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Essaie (j'ai ajouté la condition de sortie si c2 ne ramène rien) :
    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
    CREATE OR REPLACE PROCEDURE UPDATE_BILL 
    IS 
     
    TYPE CALL_REC IS RECORD(id NUMBER,msis CHAR(20),tp CHAR(3), mnt NUMBER); 
    call CALL_REC; 
    mont NUMBER; 
    CURSOR c1 IS SELECT ID,MSISDN,TYPE,MONTANT FROM CALL_I20050801RESUME; 
    CURSOR c2(id IN CALL_I20050801RESUME.ID%TYPE, msi IN CALL_I20050801RESUME.MSISDN%TYPE, 
             typ IN CALL_I20050801RESUME.TYPE%TYPE)IS 
       SELECT CHARGE FROM BILL_I20050801 WHERE SUBSCRIBER_ID=id AND TRIM(HANDSET)=TRIM(msi) 
          AND TRIM(CHASERV)=TRIM(typ) FOR UPDATE; 
    BEGIN 
     
       OPEN c1; 
          LOOP 
             FETCH c1 INTO call; 
             EXIT WHEN c1%NOTFOUND; 
             OPEN c2(call.id,call.msis,call.tp); 
                FETCH c2 INTO mont; 
              exit when c2%notfound;
                UPDATE BILL_I20050801 SET CHARGE=call.mnt WHERE CURRENT OF C2; 
             CLOSE c2; 
          END LOOP; 
       CLOSE c1; 
     
    END;

  9. #9
    Membre du Club Avatar de thief
    Inscrit en
    Décembre 2003
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 93
    Points : 47
    Points
    47
    Par défaut
    Merci à vous tous!
    j'ai essayé les deux propositions!
    Les deux tournent cependant c'est celui de Mcn qui a resolu mon pb!
    vive la communauté!!!

  10. #10
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut Opti
    J'ai corrigé mon précédent code (mauvaise valeur de l'update) mais tu avais du le voir.. et suppresssion des variables inutiles.
    Par contre, si tu ne fais que ça, le mieux est de faire un update de masse, c'est plus rapide qu'un update dans un curseur.
    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
    CREATE OR REPLACE PROCEDURE UPDATE_BILL 
    IS 
    CURSOR c1 IS 
    SELECT ID, MSISDN, TYPE, MONTANT 
    FROM CALL_I20050801RESUME; 
     
    BEGIN 
       FOR r1 IN c1 
       LOOP 
    		UPDATE BILL_I20050801 
    		SET CHARGE = r1.montant
    		WHERE SUBSCRIBER_ID = r1.ID 
    		AND TRIM(HANDSET) = TRIM(r1.msis) 
    		AND TRIM(CHASERV) = TRIM(r1.tp);
       END LOOP; 
    END;

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [PL/SQL] curseur et clause WITH
    Par ljoly dans le forum Oracle
    Réponses: 6
    Dernier message: 24/01/2006, 14h26
  2. Transact SQL - Curseurs
    Par fanch17 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 31/03/2005, 17h31
  3. T-SQL curseurs
    Par fanch17 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 31/03/2005, 13h51
  4. [PL/SQL) Curseur et nom de champ explicite
    Par Loko dans le forum Oracle
    Réponses: 6
    Dernier message: 01/12/2004, 15h07
  5. [PL/SQL] Curseur avec Paramètre
    Par blids dans le forum Oracle
    Réponses: 5
    Dernier message: 10/10/2004, 20h07

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