Hallo, ik heb een tabel met de naam CITY in Oracle SQL-ontwikkelaar, mijn probleem is hoe de procedure moet worden uitgevoerd
-- 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;
de procedure maken
CREATE OR REPLACE PACKAGE hotel AS PROCEDURE fill_city(number_city NUMBER) END hotel; / SHOW ERRORS;
en nu hoe de procedure uit te voeren?
--EXECUTE fill_city(10000) ; Begin fill_city(10000); End;
Ik heb het allebei geprobeerd, maar met een beetje geluk.
Ik kreeg de volgende foutmelding
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
Answer
Ten eerste, als u een procedure in een pakket maakt, moet de pakketnaam worden opgenomen wanneer u de procedure aanroept.
begin hotel.fill_city(10000); end; /
zou uw procedure correct moeten aanroepen.
Ten tweede heeft u problemen met de naamgeving van uw lokale variabelen. Normaal gesproken maakt u geen lokale variabelen zoals city
en postal_number
die hetzelfde zijn als de namen van kolommen in tabellen in uw database. Dat maakt het veel te gemakkelijk om fouten in je code te introduceren als je van plan bent om naar de lokale variabele te verwijzen, maar regels voor scope-resolutie betekenen dat je echt naar de kolomnaam verwijst. Als u bijvoorbeeld de volkomen geldige functie
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;
in uw WHERE
-clausule schrijft, verwijzen beide naar deptno
wordt omgezet naar de kolom in de dept
-tabel, niet naar de parameter deptno
. Dat betekent dat ongeacht welke waarde u aan de functie doorgeeft, de SELECT
-instructie elke rij van de tabel zal retourneren en dus een too_many_rows
fout. Normaal gesproken zou u een conventie bedenken voor het benoemen van variabelen en parameters die niet in strijd zijn met de naamgevingsconventies van uw tabel. Het voorvoegsel van parameters met p_
en lokale variabelen met l_
is een veel voorkomende afspraak. Dat maakt onze functie zoiets als dit
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;
De andere optie zou zijn om expliciete scoping prefixen te gebruiken bij het verwijzen naar lokale variabelen (bijv. get_dname.dname
en get_dname.deptno
) in plaats van de namen van uw lokale variabelen te wijzigen.