Procedure en pl/sql

Résolu
Bonjour,
voici ma procedure:
show err;
		CREATE OR REPLACE PROCEDURE 
		imprimer_facture(numcom IN  Commandes.num_com%TYPE)
        IS
             taux            float;
			 -- Variable pour l'affichage de l''entête de la facture
			 numeroclient    Clients.num_cli%TYPE;
			 nomclient       Clients.nom_cli%TYPE;
			 adresseclient   Clients.adress_cli%TYPE;
			 telephoneclient Clients.numtel_cli%TYPE;
			 datecommande    Commandes.date_com%TYPE;
			 
			 -- Variables dans MonCurseur pour l'affichage dans la facture
			 numeroproduit   Produits.num_pro%TYPE;
			 libelleproduit  Produits.lib_pro%TYPE;
			 quantitecommade Ligne_Coms.qte_com%TYPE;
			 prix_unitaire   Produits.prix_u%TYPE;
			 prixproduit     Produits.prix_u%TYPE;
			 MontantTotal    Commandes.mtot_com%TYPE;
			 
			 -- Déclaration du curseur
			 CURSOR MonCurseur 
			 IS
			 SELECT* FROM Commandes,Produits,Clients,Ligne_Coms
			 WHERE         Commandes.num_com  = numcom
			 AND           Clients.num_cli    = Commandes.num_com
			 AND           Ligne_Coms.num_com = Commandes.num_com
			 AND           Produits.num_pro   = Ligne_Coms.num_pro
			 ORDER BY      Produits.num_pro asc;--ligne 28
        BEGIN
		
		    taux:=0.18;
		    		
			-- Pour l'affichage de l'entête de la facture
			SELECT Clients.num_cli,Clients.nom_cli,Clients.adress_cli,Clients.numtel_cli,Commandes.Mtot_Com,Commandes.date_com 
			INTO   numeroclient,nomclient,adresseclient,telephoneclient,MontantTotal,datecommande
			FROM   Commandes,Produits,Clients,Ligne_Coms
			WHERE  Commandes.num_com  = numcom
			AND    Clients.num_cli    = Commandes.num_com
			AND    Ligne_Coms.num_com = Commandes.num_com
			AND    Produits.num_pro   = Ligne_Coms.num_pro;
			 
			 -- Affichage de l'entête de la facture 
			 DBMS_OUTPUT.PUT_LINE('Client N°    :'||numeroclient);
			 DBMS_OUTPUT.PUT_LINE('Nom          :'||nomclient);
			 DBMS_OUTPUT.PUT_LINE('Adresse      :'||adresseclient);
			 DBMS_OUTPUT.PUT_LINE('Telephone    :'||telephoneclient);
			 DBMS_OUTPUT.PUT_LINE('______________________________________________________________________________________________________________');
			 
			 -- Affichage du numero et de la date de la commande 
			 DBMS_OUTPUT.PUT_LINE('Commande N°  :'||numcom);
			 DBMS_OUTPUT.PUT_LINE('Du           :'||datecommande);
			 
			 -- Affichage des entêtes concernant les différents produits de la facture 
			 DBMS_OUTPUT.PUT_LINE('Prod N°  |      Libelle      |    QteCom    |   Prix Unitaire   |   Prix Prod   |   TVA   ');
            
			OPEN   MonCurseur;
           -- FETCH  MonCurseur INTO numeroproduit,libelleproduit,quantitecommade,prix_unitaire;
            --WHILE (MonCurseur%FOUND) 
			LOOP
			       FETCH  MonCurseur INTO numeroproduit,libelleproduit,quantitecommade,prix_unitaire;
			       prixproduit:=quantitecommade*(prix_unitaire + taux); -- Calcul du prix du produit
                   DBMS_OUTPUT.PUT_LINE(numeroproduit||'--'||libelleproduit||'--'||quantitecommade||'--'||prix_unitaire||'--'||prixproduit||'--'||taux);
            END LOOP;
			CLOSE MonCurseur;
            DBMS_OUTPUT.PUT_LINE('MONTANT TOTAL   :'|| MontantTotal ||'FCFA');             

        END ;

Il me genere cette erreur que je n'arrive pas à corriger.:
LINE/COL 	ERROR
60/11 	PL/SQL: SQL Statement ignored
60/11 	PLS-00394: nombre de valeurs erroné dans liste INTO d'une instruc tion FETCH 
SOS

6 réponses

  1. Modérateur
    Surement à cause du produit cartésien sur le select pour l'entête de commande.

    Dans le select il ne faut pas associer la table lignes de commande qui fait que le select entête de commande ramène autant de rows que la commande possède de ligne.
    1. Modérateur
      Le select doit ramener n lignes alors que tu n'en attends qu'une.
      1. Merci le nouveau code est le suivant:
        show err;
        		CREATE OR REPLACE PROCEDURE 
        		imprimer_facture(numcom IN  Commandes.num_com%TYPE)
                IS
                     taux            float;
        			 -- Variable pour l'affichage de l''entête de la facture
        			 numeroclient    Clients.num_cli%TYPE;
        			 nomclient       Clients.nom_cli%TYPE;
        			 adresseclient   Clients.adress_cli%TYPE;
        			 telephoneclient Clients.numtel_cli%TYPE;
        			 datecommande    Commandes.date_com%TYPE;
        			 
        			 -- Variables dans MonCurseur pour l'affichage dans la facture
        			 numeroproduit   Produits.num_pro%TYPE;
        			 libelleproduit  Produits.lib_pro%TYPE;
        			 quantitecommade Ligne_Coms.qte_com%TYPE;
        			 prix_unitaire   Produits.prix_u%TYPE;
        			 prixproduit     Produits.prix_u%TYPE;
        			 MontantTotal    Commandes.mtot_com%TYPE;
        			 
        			 -- Déclaration du curseur
        			 CURSOR MonCurseur 
        			 IS
        			 SELECT Produits.num_pro,Produits.lib_pro,Ligne_Coms.qte_com,Produits.prix_u FROM Commandes,Produits,Clients,Ligne_Coms
        			 WHERE         Commandes.num_com  = numcom
        			 AND           Clients.num_cli    = Commandes.num_com
        			 AND           Ligne_Coms.num_com = Commandes.num_com
        			 AND           Produits.num_pro   = Ligne_Coms.num_pro
        			 ORDER BY      Produits.num_pro asc;--ligne 28
                BEGIN
        		
        		    taux:=0.18;
        		    		
        			-- Pour l'affichage de l'entête de la facture
        			SELECT Clients.num_cli,Clients.nom_cli,Clients.adress_cli,Clients.numtel_cli,Commandes.Mtot_Com,Commandes.date_com 
        			INTO   numeroclient,nomclient,adresseclient,telephoneclient,MontantTotal,datecommande
        			FROM   Commandes,Produits,Clients,Ligne_Coms
        			WHERE  Commandes.num_com  = numcom
        			AND    Clients.num_cli    = Commandes.num_com
        			AND    Ligne_Coms.num_com = Commandes.num_com
        			AND    Produits.num_pro   = Ligne_Coms.num_pro;
        			 
        			 -- Affichage de l'entête de la facture 
        			 DBMS_OUTPUT.PUT_LINE('Client N°    :'||numeroclient);
        			 DBMS_OUTPUT.PUT_LINE('Nom          :'||nomclient);
        			 DBMS_OUTPUT.PUT_LINE('Adresse      :'||adresseclient);
        			 DBMS_OUTPUT.PUT_LINE('Telephone    :'||telephoneclient);
        			 DBMS_OUTPUT.PUT_LINE('______________________________________________________________________________________________________________');
        			 
        			 -- Affichage du numero et de la date de la commande 
        			 DBMS_OUTPUT.PUT_LINE('Commande N°  :'||numcom);
        			 DBMS_OUTPUT.PUT_LINE('Du           :'||datecommande);
        			 
        			 -- Affichage des entêtes concernant les différents produits de la facture 
        			 DBMS_OUTPUT.PUT_LINE('Prod N°  |      Libelle      |    QteCom    |   Prix Unitaire   |   Prix Prod   |   TVA   ');
                    
        			OPEN   MonCurseur;
                   FETCH  MonCurseur INTO numeroproduit,libelleproduit,quantitecommade,prix_unitaire;
                    WHILE (MonCurseur%FOUND) 
        			LOOP
        			       FETCH  MonCurseur INTO numeroproduit,libelleproduit,quantitecommade,prix_unitaire;
        			       prixproduit:=quantitecommade*(prix_unitaire + taux); -- Calcul du prix du produit
                           DBMS_OUTPUT.PUT_LINE(numeroproduit||'--'||libelleproduit||'--'||quantitecommade||'--'||prix_unitaire||'--'||prixproduit||'--'||taux);
                    END LOOP;
        			CLOSE MonCurseur;
                    DBMS_OUTPUT.PUT_LINE('MONTANT TOTAL   :'|| MontantTotal ||'FCFA');             
        
                END ;
        

        Il n'y a plus d'erreur mais
        exec imprimer_facture(00001) mde donne ceci:
        BEGIN imprimer_facture(00004); END;
        
        *
        
        ERREUR à la ligne 1 :
        ORA-01422: l'extraction exacte ramène plus que le nombre de lignes demandé
        ORA-06512: à "JOEL.IMPRIMER_FACTURE", ligne 34
        ORA-06512: à ligne 1 
        .
        1. Modérateur
          Salut,

          Dans ton fecth tu as 4 champs alors que dans le select il y a * qui ramène tous les champs de toutes les tables (ce qui n'a pas de sens).

          SELECT* FROM Commandes,Produits,Clients,Ligne_Coms

          Il faut remplacer * par la liste des champs.

          cdlt