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

SQL Oracle Discussion :

Création d'une table avec curseur


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Août 2009
    Messages
    273
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 273
    Par défaut Création d'une table avec curseur
    Bonjour,

    Je voudrais savoir ce qui ne va pas dans le code ci-dessous:

    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
    31
    32
    33
    34
    35
    36
    37
    38
     
     
    DECLARE
     
        V_T_EXISTS  NUMBER :=0;
        I  NUMBER:=0;
     
        CURSOR CUR
        IS
            SELECT ...;
    BEGIN
     
        SELECT COUNT(*) INTO V_T_EXISTS FROM ALL_TABLES WHERE TABLE_NAME='TEST';
     
        IF V_T_EXISTS = 1 THEN
     
            FOR REC IN CUR LOOP
                I := I + 1;
                BEGIN
                    UPDATE TEST
                       SET CH1 = REC.CH1
                     WHERE CH2 = REC.CH2;
                EXCEPTION
                    WHEN OTHERS THEN
                        NULL;
                END;
            END LOOP;
        ELSE
     
            EXECUTE IMMEDIATE 'CREATE TABLE TEST AS
                                SELECT ....';
            EXECUTE IMMEDIATE 'CREATE INDEX INDEX_TEST ON TEST (...)';
     
        END IF;
     
        COMMIT;
     
    END;
    J'ai le message d'erreur suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PL/SQL: ORA-00942: table or view does not exist
    Merci,

  2. #2
    Membre chevronné Avatar de xdescamp
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 300
    Par défaut
    Si la table TEST n'existe pas, le bloc PL/SQL ne compilera pas à cause de l'update sur cette table.
    Il faut cacher cet update dans un EXECUTE IMMEDIATE pour que cela fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    EXECUTE IMMEDIATE 'UPDATE TEST SET CH1 = :b1 WHERE CH2 = :b2' USING IN REC.CH1, REC.CH2;
    ...

  3. #3
    Membre éclairé
    Inscrit en
    Août 2009
    Messages
    273
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 273
    Par défaut
    Le curseur fait aussi référence à la table test


    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
    31
    32
    33
    34
    35
    36
    DECLARE
     
        V_T_EXISTS  NUMBER :=0;
        I  NUMBER:=0;
     
        CURSOR CUR
        IS
            SELECT ...
              FROM TEST T, ....
            WHERE ...;
    BEGIN
     
        SELECT COUNT(*) INTO V_T_EXISTS FROM ALL_TABLES WHERE TABLE_NAME='TEST';
     
        IF V_T_EXISTS = 1 THEN
     
            FOR REC IN CUR LOOP
                I := I + 1;
                BEGIN
                   EXECUTE IMMEDIATE 'UPDATE TEST SET CH1 = :b1 WHERE CH2 = :b2' USING IN REC.CH1, REC.CH2;
                EXCEPTION
                    WHEN OTHERS THEN
                        NULL;
                END;
            END LOOP;
        ELSE
     
            EXECUTE IMMEDIATE 'CREATE TABLE TEST AS
                                SELECT ....';
            EXECUTE IMMEDIATE 'CREATE INDEX INDEX_TEST ON TEST (...)';
     
        END IF;
     
        COMMIT;
     
    END;
    d'où le même message d'erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PL/SQL: ORA-00942: TABLE OR VIEW does NOT exist

    Est ce que l'update peut se faire de de la façon suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      EXECUTE IMMEDIATE 'UPDATE TEST SET CH1 =' || REC.CH1 || ' WHERE CH2 = '  || REC.CH2 ||';
    sans le using ?

  4. #4
    Membre chevronné Avatar de xdescamp
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 300
    Par défaut
    Citation Envoyé par Jinkas Voir le message
    Le curseur fait aussi référence à la table test
    Au temps pour moi, je n'avais pas vu.
    Il faudrait :
    - déclarer un tableau (TABLE OF...)
    - utiliser un EXECUTE IMMEDIATE 'SELECT...' BULK COLLECT INTO... pour alimenter le tableau
    - puis boucler sur le tableau.

    Citation Envoyé par Jinkas Voir le message
    Est ce que l'update peut se faire de de la façon suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      EXECUTE IMMEDIATE 'UPDATE TEST SET CH1 =' || REC.CH1 || ' WHERE CH2 = '  || REC.CH2 ||';
    sans le using ?
    Oui, mais ça sera beaucoup moins performant : l'optimiseur ne verra pas que c'est toujours la même requête; il refera donc le parsing à chaque fois, ce qui finira par remplir la mémoire s'il y a trop de volume. Autant utiliser le USING.

  5. #5
    Membre éclairé
    Inscrit en
    Août 2009
    Messages
    273
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 273
    Par défaut
    - Je n'ai pas bien compris les variables dans le EXECUTE IMMEDIATE de l'update

    - ni comment déclarer le tableau

    - je ne sais pas non plus ou faire ce 'SELECT...' BULK COLLECT INTO... pour alimenter le tableau (à la place du curseur ??? ou bien supprimer le curseur et parcourir le tableau dans le begin)

    peut être comme ça ?

    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
    declare
      type t_bc_a is table of bc.a%type;
      type t_bc_b is table of bc.b%type;
     
      l_bc_a t_bc_a;
      l_bc_b t_bc_b;
    begin
      select a, b bulk collect into l_bc_a, l_bc_b from bc;
     
      for i in l_bc_a.first .. l_bc_a.last loop
        dbms_output.put_line(l_bc_a(i) || ', ' || l_bc_b(i));
      end loop;
     
    end;
    /
    si oui, il faudrait simplement déclarer les variables qui sont récupérées dans le curseur ?

  6. #6
    Membre chevronné Avatar de xdescamp
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 300
    Par défaut
    - Pour les variables, il s'agit de "bind variables". Cela permet de déclarer des variables dans l'instruction, puis de leur assigner des valeurs au moment de l'exécution. La syntaxe et des exemples : http://download.oracle.com/docs/cd/B...3_elems017.htm ou http://download.oracle.com/docs/cd/B...61/dynamic.htm.

    - Pour le BULK COLLECT, il y a des exemples dans la doc Oracle : http://download.oracle.com/docs/cd/B...mic.htm#i18972. Le 7-4 est un exemple basique; le reste est intéressant à lire également.

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

Discussions similaires

  1. Création d'une table avec contrainte
    Par sofiane_bfm007 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 19/10/2008, 00h17
  2. Réponses: 4
    Dernier message: 22/11/2007, 19h23
  3. [OpenOffice] API : Création d'une table avec image
    Par darkendorf dans le forum API, COM et SDKs
    Réponses: 0
    Dernier message: 06/11/2007, 11h26
  4. Création d'une table avec foreign key.
    Par Paulinho dans le forum Débuter
    Réponses: 6
    Dernier message: 01/12/2005, 18h47
  5. Création d'une table avec foreign key
    Par lepierre dans le forum Langage SQL
    Réponses: 5
    Dernier message: 17/09/2004, 14h20

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