안녕하세요 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
와 같은 지역 변수를 만들지 않습니다. 따라서 지역 변수를 참조하려는 코드에서 오류를 너무 쉽게 도입 할 수 있지만 범위 확인 규칙은 실제로 열 이름을 참조하고 있음을 의미합니다. 예를 들어 WHERE
절에 완벽하게 유효한 함수
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;
를 작성하면 두 가지 모두 deptno
는 매개 변수 deptno
가 아니라 dept
테이블의 열로 확인됩니다. 즉, 함수에 어떤 값을 전달하든 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
) 로컬 변수의 이름을 변경하는 대신