Hallo, ich habe eine Tabelle mit dem Namen CITY in Oracle SQL Developer. Mein Problem ist das Ausführen der Prozedur

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

Erstellen der Prozedur

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

und wie wird die Prozedur ausgeführt?

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

Ich habe beide versucht, aber mit etwas Glück.

Ich habe den folgenden Fehler erhalten

 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 

Antwort

Wenn Sie eine Prozedur in einem Paket erstellen, muss der Paketname beim Aufruf der Prozedur angegeben werden.

begin hotel.fill_city(10000); end; / 

sollte Ihre Prozedur korrekt aufrufen.

Zweitens haben Sie Probleme mit der Benennung Ihrer lokalen Variablen. Normalerweise würden Sie keine lokalen Variablen wie city und postal_number erstellen, die den Namen der Spalten in Tabellen in Ihrer Datenbank entsprechen. Das macht es viel zu einfach, Fehler in Ihren Code einzufügen, wenn Sie auf die lokale Variable verweisen möchten, aber Regeln für die Bereichsauflösung bedeuten, dass Sie sich wirklich auf den Spaltennamen beziehen. Wenn Sie beispielsweise die perfekt gültige Funktion

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 Ihre WHERE -Klausel schreiben, verweisen beide auf deptno wird in die Spalte in der Tabelle dept aufgelöst, nicht in den Parameter deptno. Dies bedeutet, dass die Anweisung SELECT unabhängig davon, welchen Wert Sie an die Funktion übergeben, jede Zeile aus der Tabelle zurückgibt und somit eine too_many_rows Fehler. Normalerweise würden Sie eine Konvention zum Benennen von Variablen und Parametern entwickeln, die nicht mit Ihren Namenskonventionen für Tabellen in Konflikt steht. Das Präfixieren von Parametern mit p_ und lokalen Variablen mit l_ ist eine gängige Konvention. Das macht unsere Funktion zu so etwas

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; 

Die andere Option wäre, explizite Bereichspräfixe zu verwenden, wenn auf lokale Variablen verwiesen wird (dh get_dname.dname und get_dname.deptno), anstatt die Namen Ihrer lokalen Variablen zu ändern.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.