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
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.