Oracle
 sql >> Base de données >  >> RDS >> Oracle

Procédure de résolution sans paramètres

En plus des commentaires et des réponses que vous avez déjà reçus, je pense que vous avez massivement compliqué votre procédure. Vous faites les choses de manière très procédurale, plutôt que de penser par séries comme vous devriez l'être. Vous obtenez également les colonnes agrégées dans trois requêtes qui sont essentiellement identiques (par exemple, mêmes tables, conditions de jointure et prédicats) - vous pouvez toutes les combiner pour obtenir les trois résultats dans une seule requête.

Il semble que vous essayez d'insérer dans la table clienthistoricalpurchases si une ligne n'existe pas déjà pour ce client, sinon vous mettez à jour la ligne. Cela me crie immédiatement "instruction MERGE".

En combinant tout cela, je pense que votre procédure actuelle ne devrait contenir qu'une seule instruction de fusion :

MERGE INTO clienthistoricalpurchases tgt
  USING (SELECT clients.client_id,
                COUNT(DISTINCT od.productid) distinct_products,
                COUNT(od.productid) total_products,
                SUM((od.unitprice * od.quantity) - od.discount) proposed_new_balance
         FROM   orderdetails od
         INNER  JOIN orders
         ON     orderdetails.orderid = orders.orderid
         INNER  JOIN clients
         ON     orders.clientid = clients.clientid
         GROUP BY clients.client_id) src
  ON (tgt.clientid = src.client_id)
WHEN NOT MATCHED THEN
  INSERT (tgt.clientid,
          tgt.distinctproducts,
          tgt.totalproducts,
          tgt.totalcost) 
  VALUES (src.clientid,
          src.distinct_products,
          src.total_products,
          src.proposed_new_balance)
WHEN MATCHED THEN
  UPDATE SET tgt.distinctproducts = src.distinct_products,
             tgt.totalproducts = src.total_products,
             tgt.totalcost = src.proposed_new_balance;

Cependant, j'ai quelques inquiétudes concernant votre logique actuelle et/ou votre modèle de données.

Il semble que vous vous attendiez à ce qu'au plus une ligne par clientid apparaisse dans clienthistoricalpurchases. Que se passe-t-il si un identifiant client a deux commandes différentes ou plus ? Actuellement, vous remplaceriez n'importe quelle ligne existante.

En outre, voulez-vous vraiment appliquer cette logique à toutes les commandes à chaque fois qu'elle est exécutée ?