Bonjour, jai une table nommée CITY dans Oracle SQL Developer, 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;
Jai essayé les deux mais avec de la chance.
Jai reçu lerreur 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
Réponse
Premièrement, 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 correctement appeler votre procédure.
Deuxièmement, vous avez des problèmes avec la dénomination de vos variables locales. Normalement, vous ne créez pas de variables locales telles que city
et postal_number
qui sont identiques aux noms des colonnes des tables de votre base de données. Cela rend beaucoup trop facile lintroduction derreurs dans votre code lorsque vous avez lintention de faire référence à la variable locale, mais les règles de résolution de portée 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
correspondra à la colonne de la table dept
, et non au paramètre deptno
. Cela signifie que quelle que soit la valeur que vous transmettez à la fonction, linstruction SELECT
renverra chaque ligne de la table et, par conséquent, lancera un too_many_rows
erreur. Normalement, vous arriverez à une convention sur la façon de nommer les variables et les paramètres qui ne seraient pas en conflit avec les conventions de dénomination de votre table. Le préfixe des paramètres avec p_
et des variables locales avec l_
est une convention courante. Cela transforme notre fonction en quelque chose comme ceci
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;
Lautre option serait dutiliser des préfixes de portée explicites pour faire référence à des variables locales (cest-à-dire get_dname.dname
et get_dname.deptno
) plutôt que de modifier les noms de vos variables locales.