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

Langage SQL Discussion :

Truncate et procédure stockée


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Avril 2003
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 71
    Par défaut [RESOLU] Truncate et procédure stockée
    Bonjour,

    Je réalise actuellement une procédure en PL/SQL et je souhaite vider mes tables avec un TRUNCATE, mais cette opération me génère l'erreur suivante :

    PLS-00103: Encountered the symbol "TABLE" when expecting one of
    the following:
    := . ( @ % ;
    The symbol ":= was inserted before "TABLE" to continue.

    Si j'essaie de faire mon "truncate" directement sous sqlplus, il n'y a pas de problème.

    J'ai essayé un delete from nom_table et cela ne me pose pas de souci. Les procédures stockées ne gère pas les truncate?

    Merci de vos réponses

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    il faut passer par un execute immediate

  3. #3
    Membre confirmé
    Inscrit en
    Avril 2003
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 71
    Par défaut
    En clair : (je ne connais pas le execute immediate), à quoi ressemblerait le code?

    execute immediate
    truncate table nom_table
    ?

    Ca ne fonctionne pas chez moi

    Merci

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    execute immediate('TRUNCATE TABLE ... ');
    C'est une commande DDL comme le create table et elle ne peut donc pas être exécuter directement dans un code PL/SQL

  5. #5
    Membre expérimenté
    Avatar de MashiMaro
    Profil pro
    Inscrit en
    Février 2003
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 180
    Par défaut
    Pourquoi un truncate au lieu du delete ?

  6. #6
    Membre confirmé
    Inscrit en
    Avril 2003
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 71
    Par défaut
    Pourquoi un truncate au lieu du delete : bonne question... Je suis débutante et on m'a dit d'utiliser le truncate et non le delete donc j'obéis. Mais j'ai vu sur internet que le delete est plus lent car il parcourt toutes les lignes, ce que ne fait pas le truncate.

    Sinon, merci pour la commande execute.

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Exact, en plus le truncate peut libérer l'espace utilisé dans le tablespace

    Truncate me parait donc plus approprié pour vider une table

  8. #8
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 102
    Par défaut
    En fait le truncate, n'écrit pas de ligne dans le journal des logs.
    Ce qui a pour effet de ne pas pouvoir en cas de crash de ta base de restauré les données avant le dit crash. Ce qui est possible avec un delete.
    En gros il est préférable de faire un truncate sur des tables de travail plutot que des delete, car cela n'encompre pas le journal des logs et donc le disque dur pour rien

    Bon courage

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4
    Par défaut execute immediat 'TRUNCATE ...'
    dans un trigger, je veux vider une table puis y insérer d'autres données
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    execute immediate 'TRUNCATE TABLE ADMP_DELIV_PTS REUSE STORAGE';
    INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS, SSRRAANOEUD, POSTE FROM ADMP_DELIV_PTS)
     (SELECT SUBSTR(SSRRAANOEUD,1,4) || SUBSTR(POSTE01,1,5), ENTITYID, SSRRAANOEUD, 'POSTE01' FROM MV_SUPPLY_PTS
    WHERE POSTE01 is NOT NULL);
    Ca ne marche pas. Si je met un delete, ça marche !?!

    Que faire ?

    Eric

  10. #10
    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
    Par défaut Re: execute immediat 'TRUNCATE ...'
    Citation Envoyé par eric.lazzaretti
    Ca ne marche pas. Si je met un delete, ça marche !?!
    Que faire ?
    Nous préciser ce que tu entends par "Ca ne marche pas". As-tu une erreur ?

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4
    Par défaut Ca ne marche pas = ...
    Tout d'abord, merci pour votre réponse.
    Non je n'ai pas d'erreur mais le résultat du trigger est faux. Le but de ce trigger est de reconstruire une table à l'aide de plusieurs INSERT à chaque fois qu'une Vue Matèrialisée est régénérée. J'ai choisi de vider et re-remplir la table car je ne sais pas comment Oracle gère la régénération complète d'une Vue matèrialisée en terme de suivi des Insertions, Updates et delete qui ont eus lieu durant la régénération. Bref, si j'utilise DELETE, la table est bien vidée et 6257 enregistrements sont ajoutés. Si je met :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    execute immediate 'TRUNCATE TABLE ADMP_DELIV_PTS';
    à la place du DELETE, la table ADMP_DELIV_PTS contient seulement 6 enregistrements : Si maintenant je fais le truncate manuellement et que je régénère la vue matèrialisée (avec le TRIGGER sans le TRUNCATE évidemment) le résultat est bon. Je voudrais essayer d'ajouter à mon code une fonction permettant d'attendre que le truncate soit fini avant que les INSERT soient lancés mais je ne sais pas comment faire.
    Voila ce que j'essaie de faire. Merci encore de votre aide

    Eric

  12. #12
    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
    Par défaut
    Je n'avais pas vu que c'était dans un trigger. Dans un trigger vous ne pouvez pas exécuter d'instruction dml (create, drop, truncate...) sans passer par une procédure autonome (pragma autonomous_transaction Par contre vous devriez avoir l'erreur suivante :
    ORA-04092: cannot COMMIT in a trigger
    Pouvez-vous indiquer :
    - la déclaration de votre trigger (create or replace trigger ... )
    - le delete qui fonctionne.

  13. #13
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4
    Par défaut Le trigger en question
    Je n'ai pas l'erreur que vous citez. Voici donc le trigger avec le delete (et le truncate en commentaire) :
    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
    39
    CREATE OR REPLACE TRIGGER TRG_INSERT_DELIV_PTS
     AFTER INSERT OR UPDATE ON MV_SUPPLY_PTS
    DECLARE
     
     
    BEGIN
       DELETE FROM ADMP_DELIV_PTS;
     --execute immediate 'TRUNCATE TABLE ADMP_DELIV_PTS';
     
     INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS,  SSRRAANOEUD, POSTE, X_GEOM, Y_GEOM FROM ADMP_DELIV_PTS)
     (SELECT SUBSTR(SSRRAANOEUD,1,4) || SUBSTR(POSTE01,1,5), ENTITYID, SSRRAANOEUD, 'POSTE01', X_GEOM, Y_GEOM
     FROM MV_SUPPLY_PTS WHERE POSTE01 is NOT NULL);
     
    INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS, SSRRAANOEUD, POSTE, X_GEOM, Y_GEOM FROM ADMP_DELIV_PTS)
    (SELECT SUBSTR(SSRRAANOEUD,1,4) || SUBSTR(POSTE02,1,5), ENTITYID, SSRRAANOEUD, 'POSTE02', X_GEOM, Y_GEOM
     FROM MV_SUPPLY_PTS WHERE POSTE02 is NOT NULL);
     
     INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS, SSRRAANOEUD, POSTE, X_GEOM, Y_GEOM FROM ADMP_DELIV_PTS)
     (SELECT SUBSTR(SSRRAANOEUD,1,4) || SUBSTR(POSTE03,1,5), ENTITYID, SSRRAANOEUD, 'POSTE03', X_GEOM, Y_GEOM FROM MV_SUPPLY_PTS WHERE POSTE03 is NOT NULL);
     
    INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS, SSRRAANOEUD, POSTE, X_GEOM, Y_GEOM FROM ADMP_DELIV_PTS)
     (SELECT SUBSTR(SSRRAANOEUD,1,4) || SUBSTR(POSTE04,1,5), ENTITYID, SSRRAANOEUD, 'POSTE04', X_GEOM, Y_GEOM FROM MV_SUPPLY_PTS WHERE POSTE04 is NOT NULL);
     
     INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS, SSRRAANOEUD, POSTE, X_GEOM, Y_GEOM FROM ADMP_DELIV_PTS)
     (SELECT SUBSTR(SSRRAANOEUD,1,4) || SUBSTR(POSTE05,1,5), ENTITYID, SSRRAANOEUD, 'POSTE05', X_GEOM, Y_GEOM FROM MV_SUPPLY_PTS WHERE POSTE05 is NOT NULL);
     
     INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS, SSRRAANOEUD, POSTE, X_GEOM, Y_GEOM FROM ADMP_DELIV_PTS)
     (SELECT SUBSTR(SSRRAANOEUD,1,4) || SUBSTR(POSTE06,1,5), ENTITYID, SSRRAANOEUD, 'POSTE06', X_GEOM, Y_GEOM FROM MV_SUPPLY_PTS WHERE POSTE06 is NOT NULL);
     
     INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS, SSRRAANOEUD, POSTE, X_GEOM, Y_GEOM FROM ADMP_DELIV_PTS)
    (SELECT SUBSTR(SSRRAANOEUD,1,4) || SUBSTR(POSTE07,1,5), ENTITYID, SSRRAANOEUD, 'POSTE07', X_GEOM, Y_GEOM FROM MV_SUPPLY_PTS WHERE POSTE07 is NOT NULL);
     
     INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS, SSRRAANOEUD, POSTE, X_GEOM, Y_GEOM FROM ADMP_DELIV_PTS)
     (SELECT SUBSTR(SSRRAANOEUD,1,4) || SUBSTR(POSTE08,1,5), ENTITYID, SSRRAANOEUD, 'POSTE08', X_GEOM, Y_GEOM FROM MV_SUPPLY_PTS WHERE POSTE08 is NOT NULL);
     
      EXCEPTION
         WHEN OTHERS THEN
           Null;
    END TRG_INSERT_DELIV_PTS;
    Le code n'est pas joli avec ces 8 insert à la suite mais je débute et je ne sais pas comment utiliser la valeur d'une variable comme nom de champs pour faire une boucle. Par exemple (mais ça ne marche pas !) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    TYPE List_of_POSTE IS TABLE OF VARCHAR2(7);
    postes List_of_POSTE := List_of_POSTE('POSTE01', 'POSTE02', 'POSTE03', 'POSTE04', 'POSTE05', 'POSTE06', 'POSTE07', 'POSTE08');
     
     
    BEGIN
       FOR i IN postes.FIRST .. postes.LAST
       LOOP
          INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS, SSRRAANOEUD FROM ADMP_DELIV_PTS)	 		 (SELECT SUBSTR(:NEW.SSRRAANOEUD,1,4) || :NEW.POSTE01, :NEW.ENTITYID, :NEW.SSRRAANOEUD
    FROM MV_SUPPLY_PTS WHERE postes(i) is not null);
       END LOOP;

  14. #14
    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
    Par défaut Re: Le trigger en question
    Citation Envoyé par eric.lazzaretti
    Je n'ai pas l'erreur que vous citez.
    Normal l'erreur est capté par l'exception when others. C'est d'ailleurs ce qui fait que vos insertions ne se font pas.

    Essayer :
    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
    create or replace procedure TRUNC_ADMP_DELIV_PTS is
    pragma autonomous_transaction;
    begin
       execute immediate 'TRUNCATE TABLE ADMP_DELIV_PTS'; 
    end;
    /
     
    CREATE OR REPLACE TRIGGER TRG_INSERT_DELIV_PTS 
     AFTER INSERT OR UPDATE ON MV_SUPPLY_PTS 
    DECLARE 
    BEGIN 
      TRUNC_ADMP_DELIV_PTS;
      INSERT ...
    END;
    /
    Pour utiliser une boucle, vous ne pouvez vous en sortir qu'en utilisant execute immediate :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for 1 in 1..8 loop
     execute immediate 'INSERT INTO (SELECT LIB_DELIV_PTS, ID_SUPPLY_PTS, SSRRAANOEUD, POSTE, X_GEOM, Y_GEOM FROM ADMP_DELIV_PTS) 
     (SELECT SUBSTR(SSRRAANOEUD,1,4) || SUBSTR(POSTE0' || i || ',1,5), ENTITYID, SSRRAANOEUD, ''POSTE0' || i || ''' , X_GEOM, Y_GEOM FROM MV_SUPPLY_PTS WHERE POSTE0' || i || ' is NOT NULL)';
    end loop;

  15. #15
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4
    Par défaut Merci
    Tout fonctionne très bien Merci pour votre aide

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

Discussions similaires

  1. passage d'un nom de table dans une procédure stockée
    Par thierry V dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 26/07/2010, 16h48
  2. 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
  3. [Pervasive SQL ] procédure stockée
    Par magellan dans le forum Autres SGBD
    Réponses: 2
    Dernier message: 25/10/2002, 13h17
  4. Explication procédure stockée
    Par underworld dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 09/09/2002, 10h51
  5. [Comparatif] Procédures stockées, triggers, etc.
    Par MCZz dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 28/08/2002, 12h27

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