Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/10/2011, 11h53   #1
Membre habitué
 
Inscription : novembre 2008
Messages : 238
Détails du profil
Informations forums :
Inscription : novembre 2008
Messages : 238
Points : 120
Points : 120
Par défaut Optimisation de requête de mise à jour

Bonjour,

Je souhaite mettre à jour le prix d'inventaire des articles à partir de la dernière livraison avant la fin de l'exercice et de la ligne de commande d'achat correspondante.

Pour cela je rapproche la table des lignes de livraison de la table des lignes de commandes d'achat dans une vue.
Puis je transforme le montant de la ligne de commande d'achat en unité de stock.
Ensuite j'effectue la mise à jour de mon article.
Problème: je n'arrive pas à faire la mise à jour (après plus d'une heure d'attente, la mise à jour n'est pas réalisée).

Voici mes scripts SQL:

Le script de la vue pour rapprocher les livraisons des lignes de commandes d'achat et des commandes d'achat :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT al.id_article,al.id_achat_ligne, al.mnt_total_ht, al.nb_lot_cmde, al.qte_cmde, al.lg_cmde, al.tot_cmde, al.id_unite_cmde, al.id_unite_tot_cmde, tmp.date_livre, ach.num_achat
FROM toperp.t_achat_ligne al
INNER JOIN 
(
SELECT  a.id_article
      ,max(a.date_livre) AS date_livre
      ,max(a.id_achat_ligne) keep (dense_rank first ORDER BY date_livre DESC) AS id_achat_ligne
 FROM t_achat_bl_ligne a    
WHERE a.date_livre < TO_DATE('30/09/2011','DD/MM/YYYY')
GROUP BY a.id_article
) tmp
ON tmp. id_achat_ligne  = al.id_achat_ligne
INNER JOIN toperp.t_achat ach
ON al.id_achat = ach.id_achat
 WHERE al.mnt_total_ht > 0
Mon script de calcul de coût que je n'arrive pas à faire passer:

Code :
1
2
3
4
5
6
7
8
9
10
UPDATE T_ARTICLE ART 
          SET PU=(SELECT tmp.cout_unit 
                         FROM  ( SELECT a.id_article, 
                                              b.MNT_TOTAL_HT / (b.NB_LOT_CMDE  *                                            b.qte_cmde *  b.lg_cmde )  AS cout_unit
                                    FROM t_article a, V_RAPPRO_BL_ACHAT b
                                    WHERE a.id_article      = b.id_article  
                                       AND  a.id_unite_stock = id_unite_cmde                          
    AND  b.id_unite_cmde  <> b.id_unite_tot_cmde
    AND  a.id_groupe_article IN (1,3)) tmp 
         WHERE ART.id_article=tmp.id_article)
Merci d'avance.
Julien.
juju05 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 12h13   #2
Membre confirmé
 
Homme Grégoire MARTIN
Ingénieur développement logiciels
Inscription : janvier 2011
Messages : 128
Détails du profil
Informations personnelles :
Nom : Homme Grégoire MARTIN
Âge : 32
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Finance

Informations forums :
Inscription : janvier 2011
Messages : 128
Points : 225
Points : 225
Peux tu nous mettre les plan d'executions de ta vue ?

Volumes des tables ?

Code :
1
2
3
4
5
6
SELECT /*+ gather_plan_statistics */
....
 
SELECT *
FROM
    TABLE (dbms_xplan.display_cursor (format=>'ALLSTATS LAST'));
__________________
Cordialement.
ORA-007 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 12h32   #3
Membre habitué
 
Inscription : novembre 2008
Messages : 238
Détails du profil
Informations forums :
Inscription : novembre 2008
Messages : 238
Points : 120
Points : 120
La table T_article contient 46602 lignes. Il y a un index pk sur id_article. Par contre il n'y a rien sur l'id_unite_stock.

J'ai créé la vue en question. Elle contient 5608 enregistrements.

J'ai un message Erreur SQL lorsque je lance votre requête sur SQLDEVELOPPER. Je suis sous Oracle 10g.
Julien.
juju05 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 14h35   #4
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 313
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 313
Points : 5 819
Points : 5 819
Utilisez Merge à la place de l'update.
Quelle version d'Oracle ?
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 17/10/2011, 14h47   #5
Membre habitué
 
Inscription : novembre 2008
Messages : 238
Détails du profil
Informations forums :
Inscription : novembre 2008
Messages : 238
Points : 120
Points : 120
En consultant l'aide sur Oracle, le merge me permet de dissocier les update et les insert. Je conserve donc l'usage de l'update. Je ne vois pas comment cela pourrait me faire gagner du temps.

Je suis sur Oracle 10g.
juju05 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 15h39   #6
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Citation:
le merge me permet de dissocier les update et les insert.
Pas que : merge enhancements in 10g
Citation:
La table T_article contient 46602 lignes
...
J'ai créé la vue en question. Elle contient 5608 enregistrements.
Ton UPDATE tel que tu l'écris va mettre à jour les 46602 lignes de la table alors que la vue permettant le calcul ne contient que 5608 lignes.
Sans correspondance la colonne PU sera MAJ à NULL, est ce vraiment ce dont tu as besoin ?
Le MERGE pourrait peut être s'écrire comme ça :
Code :
1
2
3
4
5
6
7
8
9
merge INTO T_ARTICLE ART
USING (SELECT b.id_article,b.id_unite_cmde, b.MNT_TOTAL_HT / (b.NB_LOT_CMDE  * b.qte_cmde * b.lg_cmde )  AS cout_unit
         FROM V_RAPPRO_BL_ACHAT b
        WHERE b.id_unite_cmde  <> b.id_unite_tot_cmde) tmp
   ON art.id_article      = tmp.id_article
  AND art.id_unite_stock  = tmp.id_unite_cmde
 when MATCHED then 
  SET art.PU = tmp.cout_unit
WHERE art.id_groupe_article IN (1,3)
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 16h03   #7
Membre habitué
 
Inscription : novembre 2008
Messages : 238
Détails du profil
Informations forums :
Inscription : novembre 2008
Messages : 238
Points : 120
Points : 120
Effectivement, je n'ai aucun intérêt à mettre à jour l'ensemble des enregistrements de la table T_ARTICLE.

La requête que vous proposez me semble correct mais j'ai une erreur SQL
Code :
ORA-00969 Mot clé ON absent
Si j'essaye de mettre une parenthèse après le ON et d'inclure le 2ème champ de la jointure, j'ai une erreur "Mot clé absent".
juju05 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 16h13   #8
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
J'oublie tout le temps les parenthèses liées au ON et j'ai oublié update :
Code :
1
2
3
4
5
6
7
8
merge INTO T_ARTICLE ART
USING (SELECT b.id_article,b.id_unite_cmde, b.MNT_TOTAL_HT / (b.NB_LOT_CMDE  * b.qte_cmde * b.lg_cmde )  AS cout_unit
         FROM V_RAPPRO_BL_ACHAT b
        WHERE b.id_unite_cmde  <> b.id_unite_tot_cmde) tmp
   ON (art.id_article = tmp.id_article AND art.id_unite_stock = tmp.id_unite_cmde)
 when MATCHED then UPDATE
  SET art.PU = tmp.cout_unit
WHERE art.id_groupe_article IN (1,3)
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 16h28   #9
Membre habitué
 
Inscription : novembre 2008
Messages : 238
Détails du profil
Informations forums :
Inscription : novembre 2008
Messages : 238
Points : 120
Points : 120
Cela fonctionne.
Merci beaucoup

Bonne fin de journée.
Julien.
juju05 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h31.


 
 
 
 
Partenaires

Hébergement Web