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 :

Procédure stockée : INSERT partiel [11gR2]


Sujet :

PL/SQL Oracle

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2006
    Messages : 61
    Points : 52
    Points
    52
    Par défaut Procédure stockée : INSERT partiel
    Bonjour,

    J'ai créé une procédure stockée afin de mettre à jour une table. Cette procédure est très simple (ce qui me va bien) car elle se contente de supprimer les lignes d'une table correspondant à un paramètre passé à la procédure et de recharger les nouvelles lignes selon le même paramètre. Donc un DELETE et un INSERT.
    Lorsque je joue la procédure elle n'insère rien. Si je modifie ma clause WHERE (en fait je la supprime), elle m'insère quelque ligne mais je suis très loin des 20000 attendues.
    Si je joue ma requête manuellement (clause WHERE incluse) elle me remonte bien les 20000 lignes.
    N'étant pas du tout un expert en PL/SQL je sollicite vos lumières (mon ami google ne pas aidé, mais j'ai certainement mal cherché)
    Merci pour votre aide

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Sans voir votre code ni ne pouvoir l'appliquer sur jeu de test c'est très compliqué de vous aider.

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2006
    Messages : 61
    Points : 52
    Points
    52
    Par défaut Précisions
    Hello,
    Merci pour la réponse, effectivement il manque un peu de 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
     
     
    CREATE OR REPLACE PROCEDURE p_Test ( v_TYP_QW IN VARCHAR2)
    IS
        v_Nothing_ToDO NUMBER(2) := 0;
     
    BEGIN
     
        IF v_TYP_QW='ST' THEN
     
            DELETE STA_TB WHERE STA_TYPE_QWERY = v_TYP_QW;
     
            INSERT INTO STA_TB
            SELECT ALLTB.OWNER , ALLTB.TABLE_NAME            
            FROM ALL_ALL_TABLES ALLTB 
           WHERE ALLTB.OWNER LIKE 'A%' OR (ALLTB.OWNER LIKE 'BB%'AND ALLTB.TABLE_NAME LIKE'CC%');        
        ELSE  
             /* Nothing to do */
             v_Nothing_ToDO := 1;
        END IF ;
     
    END;

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Sur votre procédure :
    Elle ne peut pas être valide, vous avez au moins une colonne STA_TYPE_QWERY dans votre table STA_TB, hors elle n'est pas alimentée dans l'insert et je ne vois ni un owner ni un table_name aller dedans.
    Votre ELSE IF et votre variable ne servent à rien.

    De manière générale, utiliser DBMS_OUTPUT pour contrôler à chaque étape intermédiaire, par exemple :
    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 p_test (v_typ_qw in varchar2)
    is
     
    begin
        dbms_output.put_line('TYP_QW : ' || v_typ_qw);
     
        if v_typ_qw = 'ST' then
     
            delete from sta_tb
             where sta_type_qwery = v_typ_qw;
     
            dbms_output.put_line('Nb lignes delete : ' || to_char(sql%rowcount));
     
            insert into sta_tb
            select alltb.owner
                 , alltb.table_name      
              from all_all_tables alltb 
             where  alltb.owner      like 'A%'
                or (alltb.owner      like 'BB%'
               and  alltb.table_name like 'CC%');
     
            dbms_output.put_line('Nb lignes insert : ' || to_char(sql%rowcount));
        end if;
     
    end;
    /
    Et appelez votre procédure de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    set serveroutput on
     
    begin
        dbms_output.enable;
        p_test('TOTO');
        p_test('ST');
     -- rollback; -- A vous de voir
    end;
    /

  5. #5
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par CoderCool Voir le message
    Bonjour,

    ....N'étant pas du tout un expert en PL/SQL je sollicite vos lumières (mon ami google ne pas aidé, mais j'ai certainement mal cherché)
    Dans la base Oracle il y a deux moteurs: un moteur SQL et un autre PL/SQL. Dans PL/SQL lors de l'exécution d'une requête SQL le contrôle passe au moteur SQL de la base et après l'exécution de la requête le contrôle reviens dans PL/SQL Toute cela c'est pour vous dire que lorsque vous exécutez la requête sous sqlplus ou autre outil interactif puis via l'invocation de la procédure c'est toujours le même moteur SQL qui l'exécute!
    Par conséquence si vous avez des différences des comportements vous devez chercher les cause ailleurs: la requête n'est pas identique, la base n'est pas la même, la table d'origine des données a été modifiée par un autre utilisateur, etc.

  6. #6
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2006
    Messages : 61
    Points : 52
    Points
    52
    Par défaut Suite
    Bonjour,

    Merci pour cette réponse.
    Voici mon code en cours de 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
     
     
    CREATE OR REPLACE PROCEDURE p_LIST2 ( v_TYP_QW IN VARCHAR2)
    IS
        -- v_Nothing_ToDO NUMBER(2) := 0;
     
    BEGIN
     
        IF v_TYP_QW='STAT_COUNT' THEN
     
            DELETE STA_QUERIES WHERE STA_TYPE_QWERY = v_TYP_QW;
     
            INSERT INTO STA_QUERIES
     
                SELECT ALLTB.OWNER , ALLTB.TABLE_NAME ,'QUERY TEST' ,'TEST STAT_COUNT' FROM ALL_ALL_TABLES ALLTB ;
     
                dbms_output.put_line('Nb lignes insert STAT_COUNT : ' || to_char(sql%rowcount));
           ELSE
                 INSERT INTO STA_QUERIES  SELECT ALLTB.OWNER , ALLTB.TABLE_NAME , 'blabla query', 'TEST'  FROM ALL_ALL_TABLES ALLTB;
     
                 dbms_output.put_line('Nb lignes insert ELSE : ' || to_char(sql%rowcount));
           END IF;
    END;
    Si j'execute la procedure elle passe bien dans la partie 'STAT_COUNT' mais n'insère que 60 lignes. Si je joue la requête de la condition 'STAT_COUNT' je retourne 21991 lignes;
    Y-a-t-il une limite dans le SGBD, un paramètre que sur lequel je devrais jouer pour retourner toutes mes lignes ?

  7. #7
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Arrêtez de croire dans des phénomènes paranormaux!

    Quand vous exécutez disons via sqlplus, la requête Select ... elle vous renvoie 21991 lignes.
    Quand vous exécutez toujours sous sqlplus la requête insert into ... Select ... donc en dehors de votre procédure, elle crée combien des lignes ?

  8. #8
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2006
    Messages : 61
    Points : 52
    Points
    52
    Par défaut suite
    A mon age je ne crois plus trop au paranormal En revanche je veux bien une explication. Elle existe, c'est certain et je parie que je suis la cause du souci en ne faisant pas correctement quelque chose mais quoi ?
    Pour répondre à la question de MNITU (je n'ai pas dû être très clair) j'insère 21991 lignes en INSERT (...) SELECT (...)
    et si je lance la procédure via

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    exec p_List2('STAT_COUNT')
    Je n'insère que 60 lignes.

  9. #9
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2006
    Messages : 61
    Points : 52
    Points
    52
    Par défaut Fin
    Un gentil DBA m'a donné la réponse : en PL_SQL les grant role ne sont pas remontés donc je n'ai pas les mêmes droits. Voilà

  10. #10
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Tant mieux!
    Voici un jeu d'essai au minima mais qui reproduit votre scénario
    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
     
    Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 
     
    SQL> set serveroutput on
    SQL> create table t_users as select * from all_users where 1 = 2
      2  /
    Table created
    SQL> create or replace procedure load_t_users is
      2  begin
      3    delete t_users;
      4    insert into t_users select * from all_users;
      5    dbms_output.put_line (sql%rowcount||' lignes insèrées');
      6  end;
      7  /
    Procedure created
    SQL> insert into t_users select * from all_users
      2  /
    65 rows inserted
    SQL> exec load_t_users
    65 lignes insèrées
    PL/SQL procedure successfully completed
     
    SQL>
    Comme je vous ai indiqué quand le moteur PL/SQL arrive à exécuter la requête (insert into select ...) il passe la main au moteur SQL et il attends le retour et donc par voie de conséquence j'ai bien le même numéro des enregistrements crées dans le deux cases: appel de la procédure et insert direct.
    Maintenant en quoi votre cas diverge de celui ci ?

  11. #11
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par CoderCool Voir le message
    Un gentil DBA m'a donné la réponse : en PL_SQL les grant role ne sont pas remontés donc je n'ai pas les mêmes droits. Voilà
    Désolé, mais je ne vois pas comment "les grant des roles" peuvent impacter le nombre des enregistrements.

  12. #12
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2006
    Messages : 61
    Points : 52
    Points
    52
    Par défaut
    Dixit le DBA de mon client, lorsque mon code s'exécute en PL/SQL, je n'ai pas les rôles suffisants. J'avoue ne pas maîtriser la chose mais il m'a ouvert les droits nécessaires et je parviens à exécuter correctement ma procédure.
    Merci pour votre aide.

  13. #13
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Un rôle c’est un regroupement identifié (nommé) des privilèges.

    Les privilèges viennent en deux catégories : privilèges system et privilèges objets. Dans notre cas les privilèges system on peut les ignorer.

    Les privilèges objets sont ceux qui permettent l’accès aux tables, vues, etc. Exemple : je peux interroger ou bine modifier les enregistrements d'une table, etc. Mais ces privilèges sont manichéistes : j’ai le droit d’interroger ou pas disons la table en question. Elles ne permettent pas de gérer des aspects de restriction pour des raisons de confidentialités, de type je ne peux pas sélectionner le salaire des employées (colonne) ou je ne peux voir que les données de collègues qui travaillent dans le même département que moi (ligne). Pour cela Oracle offre des solutions mais qui ne sont pas basées sur les rôles.

    Bon courage pour la suite.

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

Discussions similaires

  1. Procédures stockées INSERT.
    Par notfoune dans le forum MFC
    Réponses: 2
    Dernier message: 29/11/2005, 10h35
  2. procédure stockée insert multiple
    Par gigi34 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 20/09/2005, 10h37
  3. Procédure stockée - insertion >> Merci Mr Youssef
    Par Samish dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 03/08/2005, 20h31
  4. [Procédure stockée]Insert avec renvoi clé primaire?
    Par busmik dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 26/08/2004, 16h14
  5. Procédure stocké:Insert et renvoie de la clé primair
    Par caramel dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 17/04/2003, 09h34

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