CREATE OR REPLACE FUNCTION 함수명 (매개변수, parameter, ... )RETURN 반환형IS -- 변수BEGIN -- 코드 RETURN 값;END;/
함수 삭제
DROP FUNCTION 함수명;
-- 입력된 주민번호에서 나이를 구하는 함수-- 880101-1234567-- 나이 : 현재년도 - 태어난해 + 1 (한국기준)-- 8번째 자리수가 1,2면 19-- (한국인)-- 8번째 자리수가 3,4면 20-- (한국인)-- 8번째 자리수가 5,6면 19-- (외국인)-- 8번째 자리수가 7,8면 20-- (외국인)-- 8번째 자리수가 0,9 18-- (한국인) (생략..)-- 무효하면 0살을 반환CREATE OR REPLACE FUNCTION get_age_from_ssn(ssn CHAR)RETURN NUMBERIS age NUMBER := 0; year_of_birth VARCHAR(4); yy CHAR(2); -- 판단기준으로 사용하는 flag 변수 flag CHAR(1);BEGIN IF CHECK_SSN(ssn) = 'success' THEN -- 19일지 20일지 더 할지, 18일지 판단 flag := SUBSTR(ssn, 8, 1); yy := SUBSTR(ssn,1,2); IF flag IN (1,2,5,6) THEN year_of_birth := '19'||yy; ELSIF flag IN (3,4,7,8) THEN year_of_birth := '20'||yy; ELSIF flag IN (0, 9) THEN year_of_birth := '18'||yy; END IF; age := TO_CHAR(SYSDATE, 'yyyy') - year_of_birth + 1; ELSE age:= 0; END IF; RETURN age;END;/
-- 이전 호출 시함수명(매개변수)-- 매개변수 없는 함수 호출 시-- ()는 생략가능 함수명[()]
-- ITEM_00001' 이런식으로 연번이 생성되게 하는 -- 매개변수 없는 함수를 만들기 위한 사전작업-- 사전작업-- 시퀀스 생성CREATE SEQUENCE seq_item INCREMENT BY 1 START WITH 1 MAXVALUE 9999999 CACHE 10 NOCYCLE;-- 테이블생성CREATE TABLE test_func( num CHAR(10), name VARCHAR2(30), input_date DATE DEFAULT SYSDATE, CONSTRAINT pk_test_func PRIMARY KEY(num));
-- 매개변수 없는 함수 : 시퀀스를 사용하여 10자리의-- 1씩 증가하는 고정길이형 문자열을 반환하는 함수-- 고정길이 형식 : 'ITEM_00001'CREATE OR REPLACE FUNCTION item_numRETURN CHARIS temp_num CHAR(10); seq_num NUMBER;BEGIN SELECT seq_item.nextval INTO seq_num FROM dual; -- oracle 11g부턴 함수에서 -- 시퀀스 사용 시 쿼리없이 바로 사용도 가능하다 -- seq_num := seq_item.nextval; temp_num := 'ITEM_'||LPAD(seq_num,5,0); -- temp_num := temp_num||문자열 하게되면 -- temp_num이 CHAR(10)인 뒤에 +@ 더 붙게 되어 오버플로우 발생 RETURN temp_num;END;/
-- 함수를 호출하여 지정된 형식의 번호를 얻기INSERT INTO test_func(num, name)VALUES(item_num, 'young');INSERT INTO test_func(num, name)VALUES(item_num, 'sol');INSERT INTO test_func(num, name)VALUES(item_num, 'kim');INSERT INTO test_func(num, name)VALUES(item_num, 'Lee');-- 함수 호출 시 ()는 없어도 잘 호출됨, 있어도 됨INSERT INTO test_func(num, name)VALUES(item_num(), 'Park');SELECT * FROM test_func;
BIND Variable (외부 변수)
sqlplus에서 제공하는 변수
1회용(sqlplus 종료시 사라짐)
같은 이름의 변수 선언하면 예전 변수를 덮어씀
PL/SQL이나 PROCEDURE에서 사용한 값을 sqlplus에서 저장하고 출력하기 위해 만드는 변수
프로시저의 결과를 출력하기위해 바인드 변수를 사용
-- 1. BIND 변수 선언VAR 변수명 데이터형[;]VARIABLE -- 2. 값 할당 -- PL/SQL 에서 사용할 때:변수명 := 값;-- PROCEDURE 에서 사용할 때EXECUTE 프로시저명(... :변수명)EXEC-- 3. 출력PRINT 변수명 변수명 ...
-- 선언된 BIND변수 목록보기varVARIABLE-- 생성가능한 데이터타입 확인var n t
DATE타입은 바인드변수로 만들 수 없다
PROCEDURE
프로시저(직접실행)는 자주 사용될 쿼리를 저장해 둔 것
함수(간접실행)는 자주사용될 코드(계산식 등 연산)를 저장해 둔 것
자주 사용될 쿼리문을 미리 만들어두고 사용하기 위한 것
개발자가 주로 만들고 사용, 잘 사용하면 언어코드의 간략화가 가능해짐
직접 실행
컴파일된 프로시저를 실행기를 사용하여 실행하는 것
실행기 : EXEC[EXCUTE]
함수와 다르게 반환형이 존재하지 않는다.
out parameter를 사용하여 결과값을 외부로 내보낼 수 있다.
user_procedures 딕셔너리에서 확인 가능
java에서 CallableStatement를 사용하여 프로시저를 호출할 수 있음
작성법
매개변수는 in parameter와 out parameter 2개가 존재
in parameter
프로시저 밖에 존재하는 값을 프로시저 안으로 전달하기 위해 존재
in parameter의 'IN'은 생략가능
값 할당이 불가능
사용만 가능
out parameter
프로시저 안에 값을 밖으로 전달하기 위해 존재
바인드 변수에 값 저장
언어에선 바인드 변수가 없음 -> 다른방식 사용
out parameter의 'OUT'은 생략 불가
프로시저 내부에서 값 할당이 가능
내보낼 값이 없다면 생략가능
CREATE [OR REPLACE] PROCEDURE 프로시저명 ( -- in parameter 변수명 [IN] 데이터형, ..., -- out parameter 변수명 OUT 데이터형)IS 변수선언BEGIN 코드작성END;/
-- 1. 소스작성-- 두 수를 입력받아 더하기 연산한 결과를 out parameter에 설정하는 프로시저CREATE OR REPLACE PROCEDURE proc_plus (num1 NUMBER,num2 IN NUMBER, num3 OUT NUMBER)IS -- parameter명과 같은 변수는 만들 수 없다 -- 변수명을 정할 때에는 프로시저명과 다르게 설정한다.BEGIN -- out parameter에는 값할당이 되지만 in parameter엔 값할당 안됨 -- num1 := 100; error! num3 := num1 + num2;END;/-- 2. 컴파일-- 3. 바인드 변수 선언 : VAR val NUMBER-- 4. 실행 : EXEC proc_plus(11,7,:val)-- 5. 바인드변수 출력: PRINT val
-- cp_emp2 테이블에 사원변호, 사원명, 입사일, 연봉을 추가하고-- 추가된 행의 수를 외부로 반환하는 ProcedureCREATE OR REPLACE PROCEDURE proc_insert_cpemp2( empno IN cp_emp2.empno%TYPE, ename IN cp_emp2.ename%TYPE, sal IN cp_emp2.sal%TYPE, cnt OUT NUMBER, msg OUT VARCHAR2) ISBEGIN INSERT INTO cp_emp2(empno, ename, hiredate, sal) VALUES(empno, ename, SYSDATE, sal); -- SQL%는 묵시적커서 cnt := SQL%ROWCOUNT; msg := '추가성공'; COMMIT; EXCEPTION WHEN OTHERS THEN cnt := 0; msg := '추가실패';END;/