2008-11-04 6 views
8

Dans Oracle, je souhaite créer un sproc de suppression renvoyant un nombre entier en fonction du résultat de la suppression.La procédure oracle renvoie un entier

c'est ce que j'ai jusqu'ici. J'ai essayé de mettre un RETURNS INTEGER dans mais le sproc ne compilera pas.

Répondre

2

Utilisez une fonction et le curseur implicite SQL pour déterminer le nombre de lignes supprimées

create or replace 
FUNCTION Testing 
( 
iKey IN VARCHAR2 
) RETURN INTEGER 
AS 

BEGIN 
    delete from MyTable WHERE 
    TheKey = iKey; 

    RETURN SQL%ROWCOUNT; 

END Testing; 

Cela devrait fonctionner

+0

ORA-14551: impossible d'effectuer une opération DML dans une requête – Benoit

+0

@Benoit tel qu'il devrait être, la fonction est destinée à être invoquée à partir de PL/SQL non SQL – stjohnroe

16

Une procédure ne renvoie pas de valeur. Une fonction renvoie une valeur, mais vous ne devez pas faire de DML dans une fonction (sinon vous ne pouvez pas faire référence à la fonction dans une instruction SQL, vous confondez les autorisations car normalement les DBA veulent pouvoir accorder un accès en lecture seule aux utilisateurs à toutes les fonctions pour que les utilisateurs effectuent des calculs de manière cohérente, etc.).

Vous pouvez ajouter un paramètre OUT à la procédure pour renvoyer l'état. Si le « succès » signifie qu'un ou plusieurs lignes ont été mises à jour, vous pouvez utiliser SQL% ROWCOUNT pour obtenir un décompte du nombre de lignes modifiées par l'instruction SQL avant et l'utiliser pour remplir le paramètre de retour, à savoir

CREATE OR REPLACE PROCEDURE test_proc (
    p_iKey IN VARCHAR2, 
    p_retVal OUT INTEGER 
) 
AS 
BEGIN 
    DELETE FROM myTable 
    WHERE theKey = p_iKey; 

    IF(SQL%ROWCOUNT >= 1) 
    THEN 
    p_retVal := 1; 
    ELSE 
    p_retVal := 0; 
    END IF; 
END test_proc; 

Bien sûr, d'un point de vue général de la clarté du code, je suis douteux à propos des paramètres OUT qui semblent essayer de retourner un code d'état. Vous êtes généralement mieux servi en supposant le succès et en lançant des exceptions en cas d'erreur.

0

Vous cherchez probablement une fonction à la place.

FUNCTION TESTING (iKEY IN VARCHAR2) RETURN NUMBER 
IS 
    v_count NUMBER; 
    yourNumber NUMBER; 
BEGIN 

    SELECT COUNT(*) INTO v_count 
    FROM MyTable 
    WHERE TheKey = iKey; 

    IF v_count > 0 
    THEN 
     DELETE FROM MyTable 
     WHERE TheKey = iKey; 

     SELECT COUNT(*) INTO v_count 
     FROM MyTable 
     WHERE TheKey = iKey; 

     IF (v_count = 0) 
     THEN 
      yourNumber := 1; --means successful deletion 
     END IF; 
    ELSE 
     yourNumber := 0; --means no items to delete 
    END IF; 
    return yourNumber; 

    EXCEPTION 
     WHEN OTHERS THEN 
     RETURN -1; --means error was encountered 
END TESTING; 

Remarque: Où je travaille, nous mettons généralement des fonctions dans un paquet sql.

+0

2 sélectionne plus la supprimer? Utilisez la méthode SQL% ROWCOUNT suggérée par stjohnrow à la place. –

+0

C'est vraiment cool. Je ne savais pas à ce sujet. C'est définitivement mieux. –

5

Vous pouvez utiliser une procédure stockée pour obtenir des résultats.

CREATE OR REPLACE PROCEDURE testing (iKey IN VARCHAR2, oRes OUT NUMBER) 
AS 
BEGIN 
    DELETE FROM MyTable 
     WHERE TheKey = iKey; 

    oRes := SQL%ROWCOUNT; 
END; 

Pour appeler l'utilisation de la procédure quelque chose comme:

DECLARE 
    pRes NUMBER; 
BEGIN 
    testing ('myspecialkey', pRes); 
    DBMS_OUTPUT.put_line (pRes); 
END; 
0

Le SQL%ROWCOUNT va retourner une valeur immédiatement après une DML sa valeur réinitialisera si un autre DML est exécuté.

Pour contourner le problème que j'exécutais supprime dans une boucle I a émis la commande suivante après la DML:

row_count := row_count + SQL%ROWCOUNT; 

S'il vous plaît assurez-vous déclariez et initialiser row_count := 0;

Questions connexes