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 :

Mise à jour dans une requête (curseur)


Sujet :

PL/SQL Oracle

  1. #21
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2018
    Messages
    415
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2018
    Messages : 415
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par McM Voir le message
    On est en plsql.. faut développer, utilises des variables compteurs, initialisés à 1 au changement de client, puis tu comptes les lignes, fais des sommes etc..
    j'y suis depuis deux jours, hélas je n'y arrive pas !

  2. #22
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Tout le problème c'est que personne ici n'arrive à y voir clair dans votre demande.

    Comme déjà répété par plusieurs personnes, vous exposez un jeu d'essai avec plusieurs lignes par client mais sans que nous ne puissions déterminer l'ordonnancement de ces lignes (aucun critère visible ne le permet)

    Ensuite vous parlez d'une fonction qui permet de récupérer le solde, très bien... mais dans ce cas cas, autant ajouter une colonne "Solde Initial" dans vote jeu d'essai qui simulera le résultat de cette fameuse fonction

    Pour finir, le mieux serait d'exposer un minimum de code pour avancer dans votre problématique
    Tout simplement un début d'algo :

    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
     
    DECLARE
      CURSOR C_test IS
        select  
          AGENCE,CLIENT,MONTANT_ASSURANCE,COMMISSION,SOLDE_CLIENT,
          LAG(Client) OVER(PARTITION BY Agence ORDER BY Agence, Client) AS LAST_Client
        from Ma_table
        order by COMMISSION asc;
     
      Solde_Initial NUMBER(17,4) := 0;
      Solde_Actuel  NUMBER(17,4) := 0;
     
    BEGIN
      FOR i IN C_test LOOP
     
        -- Récupération du solde initial à la première occurrence d'un client
        IF (i.LAST_Client IS NULL OR i.LAST_Client <> i.Client) THEN
          Solde_Initial := FCT_Solde_Initial;
          Solde_Actuel := Solde_Initial;
        END IF;
     
        Solde_Actuel := i.Solde_Actuel - i.Commission;
     
        UPDATE ...
        [..]
      END LOOP;
    END;
    /

    Croyez-moi, tout le monde y verra plus clair et pourra mieux vous aider car le besoin ne m'a pas l'air si complexe par contre la façon de l'exposer est très laborieuse

  3. #23
    Membre émérite
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2013
    Messages
    1 993
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 1 993
    Points : 2 499
    Points
    2 499
    Par défaut
    Citation Envoyé par Scriuiw Voir le message
    Tout le problème c'est que personne ici n'arrive à y voir clair dans votre demande.
    C'est bien pour cela que je ne réponds plus à ses questions, c'est trop long de deviner le besoin
    DBA Oracle
    Rédacteur du blog : dbaoraclesql.canalblog.com

  4. #24
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2018
    Messages
    415
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2018
    Messages : 415
    Points : 41
    Points
    41
    Par défaut
    merci pour votre retour,

    ici je n'ai pas besoin de faire un UPDATE du tout, je veux juste afficher !!

    j'ai réexpliquer plusieurs fois je ne sais pas ou il est le problème !!

    je vais illustrer par un exemple avant et après :

    1- je fais un select depuis une VUE ou un TABLEAU
    2- le résultat et sous forme :

    AGENCE ,CLIENT, MONTANT_ASSURANCE, COMMISSION, SOLDE_CLIENT

    3- exemple de données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    AGENCE  ,CLIENT,  MONTANT_ASSURANCE,  COMMISSION,   SOLDE_CLIENT
     
    A1            001              200            5                    150   SOLDE INITIAL DU CLIENT 001 = 150
    A1            001              250           10                     -
    A1            001              300           15                     -
    -------
    A1            002              150            5                    500    SOLDE INITIAL DU CLIENT 002 = 500
    A1            002              300           10                     -
    -------
    A1            003              300           15                   10     SOLDE INITIAL DU CLIENT 003 = 10

    ici on aura jamais besoin de la colonne MONTANT_ASSURANCE on travaille uniquement avec SOLDE_CLIENT et commission .

    remarque : les commissions doivent être par ordre croissant par client

    4- on commence le traitement :

    pour le client 001 :
    solde initial = 150 : commission 01 = 5
    ici dans la ligne 02 du client 001 on doit trouver (150-5) comme SOLDE = 145
    solde initial devient = 145 : commission 02 = 10
    ici dans la ligne 03 du client 001 on doit trouver (145-10) comme SOLDE = 135


    pour le client 002 :
    solde initial = 500 : commission 01 = 5
    ici dans la ligne 02 du client 001 on doit trouver (500-5) comme SOLDE = 450


    pour le client 003 :
    solde initial = 10 : commission 01 = 15
    ici il y a pas de deuxième ligne donc on fait rien !!

    en grosso-modo en fait le traitement si il y'a plus de 1 ligne pour un client donnée
    suis-je clair maintenant?

  5. #25
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Cela pourrait donner quelque chose comme ça en PL/SQL
    Y a sûrement moyen de simplifier, disons que c'est un premier jet

    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
     
    DECLARE
      CURSOR C_test IS
        select  
          AGENCE,CLIENT,MONTANT_ASSURANCE,COMMISSION,SOLDE_CLIENT,
          LAG(Client) OVER(PARTITION BY Agence ORDER BY Agence, Client) AS LAST_Client,
          LEAD(Client) OVER(PARTITION BY Agence ORDER BY Agence, Client) AS NEXT_Client
          LAG(COMMISSION) OVER(PARTITION BY Agence,Client ORDER BY Agence, Client) AS LAST_Comm,
        from Ma_table
        order by COMMISSION asc;
     
      Solde_Initial NUMBER(17,4) := 0;
      Solde_Actuel  NUMBER(17,4) := 0;
     
    BEGIN
      dbms_output.put_line('AGENCE;CLIENT;MONTANT_ASSURANCE;COMMISSION;Solde_Actuel');
      FOR i IN C_test LOOP
        -- Récupération du solde initial à la première occurrence d'un client
        IF (i.LAST_Client IS NULL OR i.LAST_Client <> i.Client) THEN
          Solde_Actuel := i.SOLDE_CLIENT;
     
          -- Calcul uniquement si le client a plus d'une ligne
          IF (i.NEXT_Client IS NOT NULL AND i.LAST_Client <> i.Client) THEN
            L_Calcul := TRUE;
          ELSE
            L_Calcul := FALSE;
          END IF;
        END IF;
     
        IF (L_Calcul) THEN
          Solde_Actuel := Solde_Actuel - NVL(i.LAST_Comm,0);
        END IF;
     
        dbms_output.put_line(i.AGENCE||';'||i.CLIENT||';'||i.MONTANT_ASSURANCE||';'||i.COMMISSION||';'||Solde_Actuel);
      END LOOP;
    END;
    /
    A tester, ça m'étonnerait que cela fonctionne du premier coup

  6. #26
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2018
    Messages
    415
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2018
    Messages : 415
    Points : 41
    Points
    41
    Par défaut
    Scriuiw je tiens a vous remercier, ça fonctionne à merveille.
    merci aux membre qui ont participé à cette discussion.

  7. #27
    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
    Pas besoin de curseur ici, une requête récursive fait le travail.
    Données
    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
    create table Mytable
    ( AGENCE                varchar2(2) not null
    , CLIENT                varchar2(3) not null
    , MONTANT_ASSURANCE     number(3)   not null
    , COMMISSION            number(5,2) not null
    , SOLDE_CLIENT          number(3)       null
    );
     
    insert into Mytable (AGENCE, CLIENT, MONTANT_ASSURANCE, COMMISSION, SOLDE_CLIENT)
    select 'A1', '001', 200,  5,  150 from dual union all
    select 'A1', '001', 250, 10, null from dual union all
    select 'A1', '001', 300, 15, null from dual union all
    select 'A1', '002', 150,  5,  500 from dual union all
    select 'A1', '002', 300, 10, null from dual union all
    select 'A1', '003', 300, 15,   10 from dual;
     
    commit;
    Requête
    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
    with cte_mytable_rn (AGENCE, CLIENT, MONTANT_ASSURANCE, COMMISSION, SOLDE_CLIENT, rn) as
    (
    select AGENCE, CLIENT, MONTANT_ASSURANCE, COMMISSION, SOLDE_CLIENT
         , row_number() over(partition by AGENCE, CLIENT order by COMMISSION asc)
      from MyTable
    )
      ,  cte_recurs (AGENCE, CLIENT, MONTANT_ASSURANCE, COMMISSION, SOLDE_CLIENT, rn) as
    (
    select AGENCE, CLIENT, MONTANT_ASSURANCE, COMMISSION, SOLDE_CLIENT, rn
      from cte_mytable_rn
     where rn = 1
     union all
    select cte.AGENCE, cte.CLIENT, tbl.MONTANT_ASSURANCE, tbl.COMMISSION
         , cte.SOLDE_CLIENT - cte.COMMISSION
         , tbl.rn
      from cte_recurs     cte
      join cte_mytable_rn tbl  on tbl.AGENCE = cte.AGENCE
                              and tbl.CLIENT = cte.CLIENT
                              and tbl.rn     = cte.rn + 1
    )
      select AGENCE, CLIENT, MONTANT_ASSURANCE, COMMISSION, SOLDE_CLIENT
        from cte_recurs
    order by AGENCE, CLIENT, COMMISSION;
    Résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    AGENCE  CLIENT  MONTANT_ASSURANCE  COMMISSION  SOLDE_CLIENT
    ------  ------  -----------------  ----------  ------------
    A1      001                    200          5           150
    A1      001                    250         10           145
    A1      001                    300         15           135
    A1      002                    150          5           500
    A1      002                    300         10           495
    A1      003                    300         15            10

  8. #28
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2018
    Messages
    415
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2018
    Messages : 415
    Points : 41
    Points
    41
    Par défaut
    Waldar Deux mots : Tu gères
    meilleure solution merci infiniment.
    TOP DU TOP

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 0
    Dernier message: 17/04/2014, 11h24
  2. Insertion d'une mise à jour dans une création de vue
    Par Ptite_Tigresse dans le forum Langage SQL
    Réponses: 0
    Dernier message: 30/08/2007, 12h34
  3. Réponses: 2
    Dernier message: 14/05/2007, 10h45
  4. Mise à jour dans une table
    Par manucha dans le forum Oracle
    Réponses: 4
    Dernier message: 01/03/2007, 11h11
  5. Mise à jour d'une requête jointe
    Par freud dans le forum Bases de données
    Réponses: 1
    Dernier message: 19/02/2007, 08h47

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