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 :

passer du insert/update à MERGE


Sujet :

SQL Oracle

  1. #1
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut passer du insert/update à MERGE
    Bonjour ,
    je voudrais passer de ca :
    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
     
    CREATE OR REPLACE TRIGGER trigger_champs BEFORE UPDATE OR INSERT ON PERSONNES
    FOR EACH ROW
    DECLARE
    compt INTEGER;
    valeur VARCHAR(10);
    BEGIN
    if (:new.diffphoto = '1') then 
       valeur:='O' ;
    else valeur:='N';
    end if;
    update asynchrone@exportSynchrone set diffphoto = valeur  ,
    date_maj= NVL(:new.date_maj, NVL( :new.dat_creation, '01/01/1999')) where id_personne 
    = substr(:new.id_personne ,1,(length( :new.id_personne )-12)) ; 
    if  SQL%ROWCOUNT = 0 then
     insert into asynchrone@exportSynchrone (diffphoto ,date_maj,id_personne)
    Values (valeur  ,NVL(:new.date_maj, NVL(:new.dat_creation, '01/01/1999'))
    ,substr(:new.id_personne,1,(length(:new.id_personne)-12)) ) ;   
    end if ; 
    END ;
    a MERGE , parce que sql%rowcount me renvoit tjrs la valeur 0 , meme si je viens de faire un insert
    comment le faire ?

  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
    Citation Envoyé par zaineb.z Voir le message
    a MERGE , parce que sql%rowcount me renvoit tjrs la valeur 0 , meme si je viens de faire un insert
    comment le faire ?
    Je dirais même que SQL%ROWCOUNT est forcément égal à 0 si tu fais l'insertion... vu que c'est la condition

    Vérifie que le WHERE est correct avec un SELECT

  3. #3
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut
    le where est bon et puis , vous savez, quand je defini ma base locale en tant que bd distante , tout marche a merveille , je sais pas pourquoi ca deconne

  4. #4
    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
    tu es sûr que le WHERE est sensé récupérer des lignes sur la base distante ? T'as des doublons sur la base distante qui permettraient de démontrer qu'il y a bien un INSERT au lieu d'un UPDATE ?

  5. #5
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut
    au faite , c'est bizarre mais bon.. lorsque je supprime un autre trigger qui se declenche en meme evenement declencheur du trigger "trigger_champs" tout marche tres bien.
    comment faire pr "synchroniser" le fonctionnement des deux triggers? a titre d'information : ils agissent sur la meme table avec les memes evenements declencheurs .

  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
    et on devine le code pour trouver le problème ?

  7. #7
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut
    voila , j'ai changé mon trigger , voila le nouveau code mais tjrs la meme erreur
    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 TRIGGER trigger_champs BEFORE UPDATE OR INSERT ON PERSONNES
    FOR EACH ROW
    DECLARE
    compt INTEGER;
    valeur VARCHAR(10);
    pic BLOB;
    stockage varchar(20):='ok';
    BEGIN
     if
    (:new.diffphoto = '1') then valeur:='O' ;
     else valeur:='N';
     end if;
     pic :=
    photo(:new.id_personne);
     compt:=mySqlrowcount(substr(:new.id_personne,1,(length( :new.id_personne)-12)));
     if compt >0 then update
    asynchrone@synchrone set diffphoto = valeur  ,date_maj= NVL( :new.date_maj, NVL(:new.dat_creation, '01/01/1999')) 
    where id_personne= substr( :new.id_personne,1,(length( :new.id_personne )-12)) ; 
    else 
    insert into asynchrone@synchrone (diffphoto ,date_maj,id_personne)   Values (valeur  ,NVL(:new.date_maj,
    NVL(:new.dat_creation, '01/01/1999')),substr(:new.id_personne,1,(length(:new.id_personne)-12)) ) ; 
    end if ;
    if stockage IS NOT NULL then 
    update asynchrone@synchrone set  stockage_photo= pic  where id_personne =substr( :new.id_personne ,1,(length( :new.id_personne)-12));  
    end if ;
     END ;

  8. #8
    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
    Crée ce trigger à la place du tient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE OR REPLACE TRIGGER trigger_champs BEFORE UPDATE OR INSERT ON PERSONNES
    FOR EACH ROW
    BEGIN
    DBMS_OUTPUT.PUT_LINE(:new.id_personne);
    END;
    /
    Ensuite pour tester ta requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SET SERVEROUTPUT ON
    INSERT INTO personnes [ce qui va bien]
    SELECT * FROM asynchrone@synchrone WHERE id_personne= substr( '&idpersonne',1,(length( '&idpersonne' )-12)) ;
    en indiquand un l'idpersonne qui est affiché au moment de l'insert.

    Je sens bien le :new.id_personne au lieu de :old.id_personne... avec ta version de trigger le id_personne est bien non nulle dans la table distante ?

  9. #9
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut
    non elle n'est pas null , c'est un champ clé

  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
    Tu continues à utiliser mySqlrowcount...
    Donne le code de cette fonction..

  11. #11
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut
    mySqlrowcount :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    CREATE OR REPLACE FUNCTION mySqlrowcount(id_p VARCHAR2) RETURN INTEGER IS 
    compt INTEGER;
    BEGIN 
    SELECT count(id_personne) INTO compt FROM asynchrone@synchrone WHERE id_personne= id_p;
    RETURN compt;
    END ;
    sinon voila le resultat du test que tu m'as demandé de faire orafrance :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SQL> INSERT INTO personnes
      2  SELECT * FROM asynchrone@synchrone WHERE id_personne= '&idpersonne';
    Entrez une valeur pour idpersonne : 1010
    ancien   2 : SELECT * FROM asynchrone@synchrone WHERE id_personne= '&idpersonne'
     
    nouveau   2 : SELECT * FROM asynchrone@synchrone WHERE id_personne= '1010'
    INSERT INTO personnes
                *
    ERREUR Ó la ligne 1 :
    ORA-00947: nombre de valeurs insuffisant

  12. #12
    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
    Pour l'erreur Orafrance à noté [ce qui va bien], à toi de mettre les bonnes colonnes !!

    Sinon, essayes ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    BEGIN
    INSERT INTO asynchrone@synchrone (diffphoto ,date_maj,id_personne)   VALUES (valeur  ,NVL(:new.date_maj,
    NVL(:new.dat_creation, '01/01/1999')),substr(:new.id_personne,1,(length(:new.id_personne)-12)) );
    EXCEPTION WHEN DUP_VAL_ON_INDEX
    THEN 
    UPDATE
    asynchrone@synchrone SET diffphoto = valeur  ,date_maj= NVL( :new.date_maj, NVL(:new.dat_creation, '01/01/1999')) 
    WHERE id_personne= substr( :new.id_personne,1,(length( :new.id_personne )-12)) ;
    END;

  13. #13
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut
    yupi yupi ca marche , merci bcp bcp a vous deux vs m'avez sauvé la vie merci et bonne journée

  14. #14
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut
    voila le nouveau trigger
    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
    CREATE OR REPLACE TRIGGER trigger_champs BEFORE UPDATE OR INSERT ON PERSONNES
    FOR EACH ROW
    DECLARE
    compt INTEGER;
    valeur VARCHAR(10);
    foto
    varchar(10):='ok';
    pic BLOB;
    BEGIN
     if (:new.diffphoto = '1') then valeur:='O'
    ;
     else valeur:='N';
     end if;
     pic := photo(:new.id_personne);
     
    compt:=mySqlrowcount(substr( :new.id_personne,1,(length(
    :new.id_personne)-12)));
     
    INSERT INTO asynchrone@synchrone (diffphoto ,date_maj,id_personne)   VALUES (valeur ,NVL(:new.date_maj,
    NVL(:new.dat_creation, '01/01/1999')),substr(:new.id_personne,1,(length(:new.id_personne)-12)) );
    EXCEPTION WHEN DUP_VAL_ON_INDEX
    THEN 
    UPDATE
    asynchrone@synchrone SET diffphoto = valeur  ,date_maj= NVL( :new.date_maj, NVL(:new.dat_creation, '01/01/1999')) 
    WHERE id_personne= substr( :new.id_personne,1,(length( :new.id_personne )-12)) ;
    update asynchrone@synchrone set  stockage_photo= pic  where
    id_personne =substr( :new.id_personne ,1,(length( :new.id_personne )-12));  
    END ;
    mais prk il met pas a jour le champ stockage_photo aussi?? je le vois NULL alors que :new.stockage_photo n'est pas NULL

  15. #15
    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
    faut chercher un peu.

    Regardes ton code, épure un peu les trucs inutiles (variable compt par exemple), et ça te sautera aux yeux.

    Pour info, le BLOB ne peut pas passer par DBLINK (sauf dans le cas d'un CREATE TABLE AS SELECT il me semble)

  16. #16
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut
    la maj passe du champ stockage_photo passe bien lorsque j'ai definis la base locale en tant que base distante , ca doit etre la meme chose je pense que lorsque je definis la base distante vraiment " distante" et non pas locale non?

  17. #17
    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
    quel est le type de stockage_photo ?

  18. #18
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut
    il est de type BLOB ,
    je tiens a signaler que la mise a jour passe trés bien lorsque j'ai definis la base locale en tant que base distante

  19. #19
    Membre régulier
    Inscrit en
    Juin 2007
    Messages
    328
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 328
    Points : 115
    Points
    115
    Par défaut
    au faite , y aurait il une autre methode pr se connecter a une bd distante autre que batabase link ?
    j'ai trouvé sur formu ceci :
    I think that the data have to be parsed into varchar2 in 32k sizes, and assembled at the other end. I am just not exactly sure, how to do the join on the other side of the db link, but a stored procedure could take care of this problem.
    une idée ?

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 16/10/2014, 11h19
  2. [AC-2010] Passer de INSERT/INTO a UPDATE
    Par Timil dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 26/05/2011, 18h36
  3. Réponses: 4
    Dernier message: 05/04/2005, 18h28
  4. Redirect de la page après un insert/update/delete
    Par mchicoix dans le forum XMLRAD
    Réponses: 5
    Dernier message: 25/02/2005, 09h31
  5. [Info] Insert/Update si problèmes divers
    Par portu dans le forum Bases de données
    Réponses: 4
    Dernier message: 15/07/2004, 10h17

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