こんにちは、Oracle SQL開発者にCITYという名前のテーブルがあります。私の問題は、プロシージャの実行方法です。
-- 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;
プロシージャの作成
CREATE OR REPLACE PACKAGE hotel AS
PROCEDURE fill_city(number_city NUMBER)
END hotel;
/
SHOW ERRORS;
そして今どのように手順を実行するのですか?
--EXECUTE fill_city(10000) ;
Begin
fill_city(10000);
End;
私は両方を試しましたが、運が良かったです。
次のエラーを受け取りました
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
まず、パッケージにプロシージャを作成する場合は、プロシージャを呼び出すときにパッケージ名を含める必要があります。
begin
hotel.fill_city(10000);
end;
/
プロシージャを正しく呼び出す必要があります。
次に、ローカル変数の命名に問題があります。通常、city
やpostal_number
などのローカル変数は、データベース内のテーブルの列の名前と同じには作成しません。これにより、ローカル変数を参照しようとするコードでエラーが発生しやすくなりますが、スコープ解決ルールでは、実際に列名を参照していることになります。たとえば、完全に有効な関数を記述した場合
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;
WHERE
句では、deptno
への参照は両方とも、パラメータdept
ではなく、deptno
テーブルの列に解決されます。つまり、関数に渡す値に関係なく、SELECT
ステートメントはテーブルのすべての行を返すため、too_many_rows
エラーがスローされます。通常、テーブルの命名規則と競合しない変数とパラメーターの命名方法についての規則が考えられます。パラメータの前にp_
を付け、ローカル変数にl_
を付けます。それは私たちの機能をこのようなものに変えます
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;
他のオプションは、ローカル変数の名前を変更するのではなく、ローカル変数(つまりget_dname.dname
およびget_dname.deptno
)を参照するときに明示的なスコーププレフィックスを使用することです。