web-dev-qa-db-fra.com

Comment exécuter la procédure dans Oracle SQL Developer

Bonjour, j'ai une table nommée CITY dans le développeur Oracle SQL, mon problème est de savoir comment exécuter la procédure

-- start the script

SET SERVEROUTPUT ON
SET LINESIZE 400
SET TIMING ON

CREATE OR REPLACE PACKAGE BODY hotel AS

    -- -----------------------------------------------------
    -- Table city
    -- -----------------------------------------------------
    PROCEDURE fill_city(number_city NUMBER) IS
        city VARCHAR2(100);
        postna_st VARCHAR2(4);

    BEGIN
        FOR st IN 1..number_city LOOP
            city:= dbms_random.string('a',100);
            postal_number:= dbms_random.value(1000,9000);
            INSERT INTO CITY(city, postal_number) VALUES (city, postal_number);
        END LOOP;
    END;

BEGIN 
    NULL;
END hotel;
/

SHOW ERRORS;

création de la procédure

CREATE OR REPLACE PACKAGE hotel AS
    PROCEDURE fill_city(number_city NUMBER)
END hotel;
/

SHOW ERRORS;

et maintenant comment exécuter la procédure?

--EXECUTE fill_city(10000) ;
Begin 
 fill_city(10000);
End;

J'ai essayé les deux mais avec chance.

J'ai reçu l'erreur suivante

 Error report:
ORA-06550: line 2, column 2:
PLS-00201: identifier 'fill_city' must be declared
ORA-06550: line 2, column 2:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:
Elapsed: 00:00:00.018
6
Andrej

Tout d'abord, si vous créez une procédure dans un package, le nom du package devra être inclus lorsque vous appelez la procédure.

begin
  hotel.fill_city(10000);
end;
/

devrait appeler correctement votre procédure.

Deuxièmement, vous avez des problèmes avec la dénomination de vos variables locales. Normalement, vous ne créeriez pas de variables locales comme city et postal_number identiques aux noms des colonnes des tables de votre base de données. Cela rend beaucoup trop facile l'introduction d'erreurs dans votre code lorsque vous avez l'intention de faire référence à la variable locale, mais les règles de résolution d'étendue signifient que vous faites vraiment référence au nom de la colonne. Par exemple, si vous écrivez la fonction parfaitement valide

CREATE OR REPLACE FUNCTION get_dname( deptno IN NUMBER )
  RETURN VARCHAR2
IS
  dname VARCHAR2(30);
BEGIN
  SELECT dname
    INTO dname
    FROM dept
   WHERE deptno = deptno;
  RETURN dname;
END;

dans votre clause WHERE, les deux références à deptno seront résolues dans la colonne de la table dept, pas dans le paramètre deptno. Cela signifie que, quelle que soit la valeur que vous transmettez à la fonction, l'instruction SELECT renverra chaque ligne de la table et, par conséquent, lancera un too_many_rows Erreur. Normalement, vous trouveriez une convention sur la façon de nommer les variables et les paramètres qui n'entreraient pas en conflit avec vos conventions de dénomination de table. Préfixer les paramètres avec p_ et les variables locales avec l_ est une convention courante. Cela transforme notre fonction en quelque chose comme ça

CREATE OR REPLACE FUNCTION get_dname( p_deptno IN NUMBER )
  RETURN VARCHAR2
IS
  l_dname VARCHAR2(30);
BEGIN
  SELECT dname
    INTO l_dname
    FROM dept
   WHERE deptno = p_deptno;
  RETURN l_dname;
END;

L'autre option serait d'utiliser des préfixes de portée explicites lors de la référence aux variables locales (c'est-à-dire get_dname.dname et get_dname.deptno) plutôt que de modifier les noms de vos variables locales.

10
Justin Cave