Witam Mam tabelę o nazwie CITY w programie Oracle SQL Developer, mój problem polega na tym, jak uruchomić procedurę

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

tworzenie procedury

CREATE OR REPLACE PACKAGE hotel AS PROCEDURE fill_city(number_city NUMBER) END hotel; / SHOW ERRORS; 

a teraz jak wykonać procedurę?

--EXECUTE fill_city(10000) ; Begin fill_city(10000); End; 

Próbowałem obu, ale bez powodzenia.

Otrzymałem następujący błąd

 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 

Odpowiedź

Po pierwsze, jeśli tworzysz procedurę w pakiecie, nazwa pakietu będzie musiała być dołączona podczas wywoływania procedury.

begin hotel.fill_city(10000); end; / 

powinno poprawnie wywołać twoją procedurę.

Po drugie, masz problemy z nazewnictwem zmiennych lokalnych. Zwykle nie tworzyłbyś zmiennych lokalnych, takich jak city i postal_number, które są takie same jak nazwy kolumn w tabelach w Twojej bazie danych. To sprawia, że wprowadzanie błędów w kodzie, gdy zamierzasz odwoływać się do zmiennej lokalnej, jest zbyt łatwe, ale reguły rozpoznawania zakresu oznaczają, że naprawdę odwołujesz się do nazwy kolumny. Na przykład, jeśli wpiszesz całkowicie poprawną funkcję

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; 

w klauzuli WHERE, oba odwołania do deptno zostanie rozstrzygnięte do kolumny w tabeli dept, a nie do parametru deptno. Oznacza to, że bez względu na wartość przekazaną do funkcji instrukcja SELECT zwróci każdy wiersz z tabeli, a tym samym wyrzuci too_many_rows błąd. Zwykle należałoby wymyślić konwencję nazywania zmiennych i parametrów, które nie kolidowałyby z konwencjami nazewnictwa tabel. Przedrostki parametrów za pomocą p_ i zmiennych lokalnych za pomocą l_ to jedna wspólna konwencja. To zmienia naszą funkcję w coś takiego

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; 

Inną opcją byłoby użycie jawnych przedrostków określających zakres podczas odwoływania się do zmiennych lokalnych (np. get_dname.dname i get_dname.deptno) zamiast zmieniać nazwy zmiennych lokalnych.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *