Bună ziua am un tabel numit CITY în oracle SQL developer, problema mea este cum să rulez procedura
-- 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;
crearea procedurii
CREATE OR REPLACE PACKAGE hotel AS PROCEDURE fill_city(number_city NUMBER) END hotel; / SHOW ERRORS;
și acum cum să executați procedura?
--EXECUTE fill_city(10000) ; Begin fill_city(10000); End;
Le-am încercat pe amândouă, dar cu noroc.
Am primit următoarea eroare
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ăspuns
Mai întâi, dacă creați o procedură într-un pachet, numele pachetului va trebui inclus atunci când apelați procedura.
begin hotel.fill_city(10000); end; /
ar trebui să invoce corect procedura dvs.
În al doilea rând, aveți probleme cu denumirea variabilelor dvs. locale. În mod normal, nu veți crea variabile locale precum city
și postal_number
care sunt identice cu numele coloanelor din tabelele din baza de date. Acest lucru face mult mai ușor să introduceți erori în codul dvs. în cazul în care intenționați să faceți referire la variabila locală, dar regulile de rezoluție a domeniului de aplicare înseamnă că vă referiți cu adevărat la numele coloanei. De exemplu, dacă scrieți funcția perfect validă
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;
în clauza WHERE
, ambele referințe la deptno
se va rezolva la coloana din tabelul dept
, nu la parametrul deptno
. Asta înseamnă că, indiferent de valoarea pe care o transmiteți funcției, instrucțiunea SELECT
va returna fiecare rând din tabel și, astfel, va arunca un too_many_rows
eroare. În mod normal, veți veni cu o convenție despre cum să denumiți variabilele și parametrii care nu ar intra în conflict cu convențiile de numire a tabelelor. Prefixarea parametrilor cu p_
și variabilele locale cu l_
este o convenție obișnuită. Asta transformă funcția noastră în ceva de genul acesta
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;
Cealaltă opțiune ar fi să folosim prefixuri explicite de scop atunci când ne referim la variabile locale (adică get_dname.dname
și get_dname.deptno
) mai degrabă decât să modificați numele variabilelor dvs. locale.