Dobrý den, mám tabulku s názvem CITY v Oracle SQL Developer, můj problém je, jak spustit proceduru
-- 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;
vytvoření procedury
CREATE OR REPLACE PACKAGE hotel AS PROCEDURE fill_city(number_city NUMBER) END hotel; / SHOW ERRORS;
a jak nyní postup provést?
--EXECUTE fill_city(10000) ; Begin fill_city(10000); End;
Zkoušel jsem obojí, ale s trochou štěstí.
Dostal jsem následující chybu
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
Odpovědět
Nejprve, pokud vytváříte proceduru v balíčku, bude nutné při volání procedury zahrnout název balíčku.
begin hotel.fill_city(10000); end; /
by měl správně vyvolat váš postup.
Zadruhé, máte problémy s pojmenováním místních proměnných. Normálně byste nevytvářeli místní proměnné, jako jsou city
a postal_number
, které jsou stejné jako názvy sloupců v tabulkách v databázi. Díky tomu je příliš snadné zavádět chyby do kódu, kde chcete odkázat na místní proměnnou, ale pravidla rozlišení oboru znamenají, že opravdu odkazujete na název sloupce. Pokud například do klauzule WHERE
napíšete dokonale platnou funkci
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;
, oba odkazy na deptno
vyřeší sloupec v tabulce dept
, nikoli parametr deptno
. To znamená, že bez ohledu na to, jakou hodnotu předáte funkci, příkaz SELECT
vrátí každý řádek z tabulky, a tedy hodí too_many_rows
chyba. Za normálních okolností byste přišli s konvencí, jak pojmenovat proměnné a parametry, které by nebyly v rozporu s konvencemi pojmenování tabulek. Předpona parametrů p_
a lokálních proměnných pomocí l_
je jednou běžnou konvencí. Tím se naše funkce promění v něco takového.
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;
Druhou možností by bylo použití explicitních předpon rozsahu, když odkazujeme na místní proměnné (tj. a get_dname.deptno
) namísto změny názvů místních proměnných.