모듈의 기초
1. 모듈이란
모듈에는 2가지 종류가 있다.
하나는 프로시져(Procedure), 다르게 말해 서브루틴 입니다.
다른 하나는 펑션(Fuction), 다르게 말해 함수 입니다.
서브루틴은 어떤 특정의 작업을 행합니다.
펑션은 어떤 특정의 작업을 행한 후에 하나의 회답을 냅니다.
예를들어 (먹는다)하는 처리가 있다고 합시다. 이것은 서브루틴이라면, 먹는다는 작업을 하는 것만입니다만, 이것이 펑션이라면 먹는다라는 작업에 대해, 그 평가로 맛있었다, 또는 맛없었다 같은 것을 회답한다.
2. 모듈 타입
모듈은 두가지의 타입이 있다.
하나는 프로시져(Procedure), 다른 하나는 펑션(Fuction)이다.
3. 모듈의 명칭
모듈은 고유의 명칭을 갖고 있다.
유저 프로그래머가 모듈을 다루는 경우, 모듈 명칭을 사용합니다.
4. 파라메타 리스트(인수)
모듈은 제로 이상 복수의 파라메타(인수)를 담당하고, 기본적으로 같은 작업을 매번 비묘하게 다른 느낌을 행합니다.
예를들어 (나메루: 맛보다,체험하다)라는 모듈이 있다고 합시다.
모듈 (나메루: 맛보다,체험하다)에 대해서, 파라메타 5번을 넘겨서 실행시키면, 5번을 (나메루: 맛보다,체험하다)합니다.
모듈 (나메루: 맛보다,체험하다)에 대해서, 파라메타 3번, 7번을 넘겨서 실행시키면 3번을 7회 (나메루: 맛보다,체험하다)합니다.
5. 리턴값(모로리치, 카에리치)
함수(펑션)은 그 자체가 하나의 값을 갖고 있습니다.
예를들어 함수 (나메루)가 나메따 감상을 반환합니다. 그 함수에 대해서, 파라메타 4번을 건내서 실행시키면, 함수 (나메루)는 잘했다 또는 못했다 같은 리턴값을 반환합니다.
데이터형의 기초
데이터형은 문자나 숫자를 다루는 경우에 그 종류를 명시한 것으로, 주로 문자열형과 수치형, 특수한 앵커구성, 유저프로그래머가 작성한 유저형 같은것이 있습니다.
1. 일반적인 형
1) VARCHAR2
문자형입니다. 문자형을 다룹니다. 최대문자열수는 4000문자 정도 입니다.
VARCHAR의 버젼업판 이라서 2라고 합니다.
형제로 CHAR, VARCHAR, LONG이 있습니다.
2) NUMBER
수치형입니다. 수치형을 다룹니다.
정수, 실수, 正の数、負の数 무엇에도 있습니다.
형제로 FLOAT같은 것이 있습니다.
3) BINARY_INTEGER
正の整数のみ를 따릅니다.
BINARY는 2진수, INTEGER는 정수의 의미입니다.
4) BOOLEAN
참 또는 거짓의 값을 갖고 있습니다. TRUE은 참, FALSE는 거짓이라는 것도 있습니다.
TRUE의 값은 -1(불 비트 온), FALSE는 0(불비트 오프)입니다.
5) 테이블형
데이터베이스의 테이블의 형입니다.
테이블 명칭%ROWTYPE로 사용합니다.
2. 앵커 구성
앵커 구성은 TYPE와 ROWTYPE의 2종류가 있고, 다은 데이터를 참조해서 그 테이터형을 카피한 특수한 것입니다. 모두 머리에 %를 붙여서 사용합니다.
이것을 사용하면, {어떤 테이블의 항목을 받는 형}을 말하는 형에 선언하는 것이 가능합니다.
TYPE는 보통의 변수명에 사용합니다.
ROWTYPE는 테이블 자체를 가리키고, 조금 다른 사용법을 갖고 있습니다.
변수명칭%TYPE나, 테이블명칭%ROWTYPE로 하는 형으로 사용합니다.
3. 유저 정의형
유저 프로그래머가 편의대로 만드는 것이 가능한 형입니다.
SUBTYPE 유저정의형명칭 IS 형명칭 [ := 초기값 ]; 으로 기술합니다.
유저 정의형명칭에는 형의 특징을 쓴 명칭을 자유롭게 붙입니다.
형명칭에는 VARCHAR2같은 기존의 형과 다른 TYPE등의 양커 구성을 써서, 특정형으로 합치는 것도 가능합니다.
서식은 다르지만, 유저프로그래머가 임의로 제작가능한 레코드형이 있습니다.
RECODE ( 항목명 형명 [ 항목명 형명 ] )
레코드 형은 임의의 레코드형을 작성하는 것입니다.
주로 커서의 리턴값이나 받음, 선언으로 사용됩니다.
1) 모듈 헤더
1/ 모듈 타입
PROCEDURE나 FUCTION을 가리킵니다.
2/ 모듈 명칭
유저프로그래머가 임의로 지정합니다.
명칭은 다은 모듈과 중복되고, 기능을 표시하기 쉬운 이름을 붙입니다.
3/ 파라메타 리스트 (인수)
모듈이 받은 파라메타의 명칭과 타입과 형과 초기값을 파라메타 수로 나눈것을 지정합니다.
명칭과 형은 필수로, 파입형과 초기값은 생략할 수 있습니다.
타입은 그 파라메타가 입력용인가 출력용인가를 표시하고, 생략하면 입력용으로 확인됩니다.
초기값은 타입이 입력용인지 입출력용인지를 지정할 수 있습니다.
이것을 생략하면 초기화는 되지 않습니다.
4/ 리턴값
모듈 타입이 FUNCTION(함수)일 때, 함수가 반환하는 리턴값의 형을 지정합니다.
펑션은 리턴값의 형을 생략할 수 없습니다.
2) 모듈의 선언부
모듈내에 사용하는 변수나 정수, 유저 정의형, 커서, 로컬 모듈을 선언합니다.
이것은 모듈 독자적인 것으로 외부에서 참조할 수 없습니다.
3) 모듈의 본체부
모듈의 동작을 기술합니다.
사양에 선언해둔 변수나 커서를 써서, 목적의 작업을 합니다.
4) 모듈의 사양
( FUNCTION | PROCEDURE )
변수명칭(
[ 인수명칭 [ IN | OUT | IN OUT ] 형 [ ( := | DEFAULT ) 초기값 ]
[, 인수명칭・・・] ] ) RETURN 형
IS
함수 내에 사용하는 변수나 커서 등을 선언
BEGIN
함수 내용
RETURN 리턴값
EXCEPTION
예외(에라 시)의 처리
RETURN 리턴값
END;
3. FUNCTION과 PROCEDURE의 다른점에 대해서
함수(펑션)은 리턴값을 갖고 있는 점만 프로시져와 다릅니다.
그래서 다음의 두가지 점이 함수(펑션)에는 있고 프로시저에는 없습니다.
1) 레더의 최후의 RETURN값의 형 선언
2) BEGIN구와 EXCEPTION구의 RETURN문
4. 인수에 대해서
1) 인수의 타입
인수에는 세 개의 타입이 있습니다.
1/ 입력용 IN
유저 프로그래머로 부터 데이터가 건내집니다.
이 인수에는 초기값이 지정되어, 유저프로그래머가 데이터를 건내지 않은 때(생략한 때), 이 초기값이 쓰입니다. 이 인수는 정수입니다.
모듈내에 이 인수값을 참조하는 것은 가능합니다만, 다른 값을 대입하는 것은 할 수 없습니다.
2/ 출력용 OUT
유저 프로그래머로부터 회답을 받은 변수를 건내받을 수 있습니다.
유저 프로그래머는 이 인수를 생략할 수 없습니다.
이 인수에 초기값을 지정하는 것은 할 수 없습니다.
이 인수는 특수한 정수입니다. 참조할 수 없습니다.
값의 대입은 할 수 있지만, 대입한 값은 바로는 반영되지 않습니다.
그것이 반영되는 것은 모듈이 정상적으로 종료해, 제어가 유저 프로그래머로 옮겨갔을 때입니다.
모듈이 예외처리에 종료한 경우는 사전에 대입을 하고 있어도, 그 값은 반영되지 않습니다.
이 인수에 대입할 수 있는 데이터형은 변수만 가능합니다.
정수나 리터럴값, 식의 대입은 할 수 없습니다.
3/ 입출력용 IN OUT
유저 프로그래머는 이 인수를 생략할 수 없습니다.
이 인수에는 초기값을 지정하는 것이 가능합니다.
그 경우, 유저 프로그래머는 지정한 회답을 갖은 변수에 미리 설정되어있던 값은 초기치에 의해서 갱신됩니다.
이 인수는 참조 가능하고, 대입 가능하고, 대입은 곧바로 반영됩니다.
즉 모듈내에서, 보통 변수와 같이 취급 할 수가 있습니다.
2) 가상파라메타와 실파라메타에 대해
유저의 입장으로 본 유저가 지정한 파라메타를 실파라메타, 모듈 내부에서 다루어지는 파라메터를 가상파라메타 라고 합니다.
3) 인수 위치의 지정에 대해서
함수나 프로시저를 호출할 때에 괄호안에 지정하는 변수나 값을 파라메타라고 하여, 그 열거법에 대해서 PL/SQL에서는 두 종류의 방법이 있습니다.
1/ 위치지정법
통상, 다른 언어에서도 함수에 대한 인수의 차례는 완전하게 정해져 있어 유저 프로그래머가 이위치를 바꾸는 것은 허용되지 않습니다.
이때, [왼쪽에서 몇번째는 무슨 인수]라는 것은 위치적으로 제대로 정해져 있어 이와같이 파라메터가 인도되는 것을 위치지정법 이라고 합니다.
예를들면 모듈 (마시러 간다 (누구와, 어디에))라는 것이 있다고 합시다.
이 때, (마시러 간다 (누구와, 어디에))라는 모듈을 실행했을 경우, 사오리와 신주쿠에 마시러 간다.라고 올바르게 해석됩니다만, 이 차례를 바꾸어 (마시러 간다 (긴자, 부장))라고 모듈을 실행해 버렸을 경우, 그 해석은 (부장에게 긴자와 마시러 간다)라고 이상하게 해석됩니다.
위치지정법은 파라메터의 차례를 바꿔서는 안됩니다.
컴파일 에러가 되면 그래도 운이 좋은 것이고, 버그로 발견되면 큰 일입니다.
2/ 이름지정법
통상, 다른 언어에도 함수에 대한 인수의 차례는 완전하게 정해져 있어서, 유저 프로그래머가 위치를 바꾸는 것은 허용되지 않습니다.
그렇지만, PL/SQL에는 이것을 유저 프로그래머가 자유롭게 지정할 수 있습니다.
그것을 이름지정법이라고 합니다.
조금 소스가 길어지지만, 인수가 모듈에 어떻게 해석될지가 소스를 본 것만으로 알수 잇게 됩니다. 대입연산자는 = 입니다.
좌변이 가상파라메터로 우변이 실파라메터가 됩니다.
5. 선언부에서 선언하는 것
모듈의 선언부에는 모듈 안에서 취급하는 변수들이 다양한 부품을 선언해 둡니다.
선언할 수 있는 것으로서는 변수, 정수, 커서, 모듈 등이 있습니다.
1) 변수와 정수의 선언에 대해서
변수명 [ CONSTANT ] 형명 [ := 초기값 ];
모듈의 선언부에서 선언된 변수나 정수는 모듈의 본체부에서 사용할 수 있습니다.
변수명은 유저 프로그래머가 자유롭게 붙입니다.
CONSTANT를 지정하면, 정수의 정의가 됩니다.
형명은 VARCHAR2 등의 기종의 형태외, 테이블명.항목명%TYPE나, 테이블%ROWTYPE등의 앵커 속성을 지정하는 것도 가능합니다.
초기값을 붙일지 말지는 유저 프로그래머의 자유입니다만, 정수의 경우는 생략 불가입니다.
정수로서 미리 결정된 값의 일을 매직값 이라고 합니다.
그에 대해, 프로그램상에 직접 기술되는 값을 리터럴값 이라고 합니다.
프로그램의 상식으로 리터럴값의 사양은 정수(매직값)로서 선언합니다.
2) 커서의 선언에 대해서
선언
CURSOR 커서명(
[ 인수명칭 [ ( IN | OUT | IN OUT ) ] 형、인수명칭・・・]
) [ RETURN 형명 ]
IS
SQL문
열기
OPEN 커서명([인수명칭、인수명칭・・・]);
취득
FETCH 커서명 [ INTO 리턴값을 취하는 변수];
닫기
CLOSE 커서명
커서는 SQL문을 미리 정의해 두는 것입니다.
주로, 본체부의 소스를 깨끗이하기 위해 사용합니다.
OPEN 했을 때, 선언되고 있던 SQL가 실행되어 그 회답군이 메모리상에 작성 됩니다.
유저 프로그래머는 그 회답을 FETCH로 취득합니다.
오픈 시에는 인수를 지정할 수가 있습니다.
커서의 정의시에 그 인수를 어떻게 사용할까 미리 선언해 두어, 범용적인 커서를 작성할 수가 있습니다.
회답군의 수만큼 FETCH를 실행할 수가 있어 모든 회답을 메모리상으로부터 다 회수했을 때, CLOSE를 실행해 커서의 처리를 종료합니다.
회답군의 종료는 커서명%FOUND가 거짓(FALSE = IF문의 판정에 걸리지 않았을 때)이 될 때 입니다.
OPEN하고 있지 않는 커서를 CLOSE해서는 안됩니다.
패키지 사양에 커서를 선언할 때, 커서의 사양을 나타내지 않으면 안되기 때문에, 리턴치가 필요합니다. 모듈이나 사용할때에는 신경 쓸 필요는 없습니다.
3) 로컬 모듈의 선언에 대해서
모듈안에 모듈을 만들수 있습니다.
이 때에 하위의 모듈을 로컬 모듈이라고 합니다.
모듈의 선언부에 선언한 것 이외, 통상적으로 모듈을 선언하는 것과 다르지 않습니다.
모듈중에서 밖에서 참조할 수 없다고 하는 점 이외, 선언 및 사용법은 보통의 모듈과 서로 다릅니다.
4) 모듈의 오버로드에 대해
모듈은 몇개의 같은 명칭을 갖는 것을 작성할 수가 있습니다.
같은 명칭의 모듈이 다수 존재하고, 각각의 동작이 차이가 나는 것을 모듈의 오버로드 라고 합니다.
1/ 파라메터의 데이터형 그룹의 상위 컴파일러는 이러한 같은 명칭을 가지는 모듈을 파라메터로 구별합니다. 따라서 오버로드 되고 있는 모듈의 파라메터는 적어도 한개이상의 형태가 차이가 나지 않으면 안됩니다.
VARCHAR와 VARCHAR2의 차이는 해당하지 않습니다.
파라메터에 문자열이 지정되었을 경우, 문자열이 CHAR형인가 VARCHAR형인가 VARCHAR2형인가, LONG형인지 컴파일러가 판단하기 어려운 경우입니다.
이것이 수치를 지정했을 경우에도 해당하지 않습니다.
오버로드되고 있는 모듈 간에 최저 1개의 파라메터의 데이터형 그룹이 차이가 나지 않으면 안됩니다. 덧붙여서 IN이나 OUT의 타입의 차이는 데이터형의 식별에는 고려되지 않습니다.
따라서 타입이 다르다고, 파라미터의 차이점이 되는 것은 아닙니다.
또, RETURN의 형태가 다르다는 것도 마찬가지로 차이점이 되는 것은 아닙니다.
어디까지나 파라메터의 형태가 전혀 다르다는 것이 전제입니다.
2/ 유효 범위가 같은 것
비록 오버로드의 파라메터의 룰에 완전하게 따르고 있어도, 그것이 유효한 범위의 다른 장소에서 선언되어서는 안됩니다.
예를 들어, 네스토 안에 로컬 모듈을 선언해 두어, 한층 더 그 아래 계층의 네스토에 같은 명칭의 모듈을 선언하려고 하면, 컴파일러 에러가 발생합니다.
왜냐하면 오버로드 되는 모듈은 같은 계층에 있어야 하는 제한이 있어서, 계층이 다른 모듈 간에는 오버로드는 되지 않습니다.
그럼에도 같은 명칭의 모듈을 선언했기 때문에, 오버로드 함수도 아닌데 같은 모듈 명칭이 사용되었다라고 컴파일 에러가 발생합니다.
5) 네스트에 대해서
모듈의 본체부에는 독립된 본체부를 작성할 수가 있습니다.
더욱 그 본체부안에, 본체부를 작성할 수가 있습니다.
이와 같이, 프로그램 안에서 계층이 있는 것을 네스트라고 합니다.
PL/SQL의 본체부의 네스트는 BEGIN ~ END안에 BEGIN ~ END를 넣는 형태가 됩니다.
PL/SQL로 BEGIN ~ END의 네스트를 사용하는 이점으로는 안에 EXCEPTION(예외처리)을 기술할 수 있는 점이 있습니다.
(도중에 에러가 나도 다음 처리로 옮기고 싶다)라고 하는 경우, 에러가 발생하면 그 제어는 강제적으로 EXCEPTION에 처리가 없는 경우는 모듈이 종료해 버립니다.
그러나 모듈안에 네스트를 만들어, 그 네스트안에 EXCEPTION을 지정해 주면, 에러시의 예외 처리가 네스트의 내부만으로 처리되고, 처리가 끝나고 진행되는 구조를 만들수가 있습니다.