함수 호출
이제 실제로 함수를 호출해 보자. 함수 호출 방식은 매개변수의 존재 유무에 따라 함수명과 매개변수를 명시하기도 하고, 함수명만 명시하기도 한다. 그리고 함수는 반환 값이 있으므로 SELECT 문장에서 사용할 수도 있고 PL/SQL 블록 내에서도 사용할 수 있다.
<매개변수가 없는 함수 호출>
함수명 혹은 함수명()
<매개변수가 있는 함수 호출>
함수명(매개변수1, 매개변수2,...)
SQL 함수와 마찬가지로 PL/SQL 함수는 SELECT문에서 사용할 수 있다. my_mod 함수를 호출해 보자.
입력
SELECT my_mod(14, 3) reminder
FROM DUAL;
결과
REMINDER
------------
2
14/3을 하면 몫이 4이고 나머지가 2이며 my_mod 함수도 정확히 2를 반환했다. 또 다른 함수를 만들어 보자. 이번에는 국가(countries) 테이블을 읽어 국가번호를 받아 국가명을 반환하는 함수를 만들어보자.
입력
CREATE OR REPLACE FUNCTION fn_get_country_name ( p_country_id NUMBER )
RETURN VARCHAR2 -- 국가명을 반환하므로 반환 데이터 타입은 VARCHAR2
IS
vs_country_name COUNTRIES.COUNTRY_NAME%TYPE;
BEGIN
SELECT country_name
INTO vs_country_name
FROM countries
WHERE country_id = p_country_id;
RETURN vs_country_name; -- 국가명 반환
END;
결과
FUNCTION FN_GET_COUNTRY_NAME이(가) 컴파일되었습니다.
이 함수는 매개변수로 NUMBER 타입의 국가번호를 받아 countries 테이블에서 해당 국가명을 가져와 vs_country_name 변수에 받아 이를 반환하고 있다. 이 함수를 호출해 보자.
입력
SELECT fn_get_country_name (52777) COUN1, fn_get_country_name(10000) COUN2
FROM DUAL;
결과
COUN1 COUN2
------------------------ ------------------
Denmark
국가번호 52777는 덴마크지만, 10000 번호를 가진 국가는 국가 테이블에 존재하지 않아 NULL이 반환되었다. 이번에는 해당 국가가 없으면 NULL 대신 ‘없음’이란 문자열을 반환하도록 위 함수를 수정해 보자.
입력
CREATE OR REPLACE FUNCTION fn_get_country_name ( p_country_id NUMBER )
RETURN VARCHAR2 -- 국가명을 반환하므로 반환 데이터타입은 VARCHAR2
IS
vs_country_name COUNTRIES.COUNTRY_NAME%TYPE;
vn_count NUMBER := 0;
BEGIN
SELECT COUNT(*)
INTO vn_count
FROM countries
WHERE country_id = p_country_id;
IF vn_count = 0 THEN
vs_country_name := '해당국가 없음';
ELSE
SELECT country_name
INTO vs_country_name
FROM countries
WHERE country_id = p_country_id;
END IF;
RETURN vs_country_name; -- 국가명 반환
END;
결과
FUNCTION FN_GET_COUNTRY_NAME이(가) 컴파일되었습니다.
매개변수로 들어오는 국가가 있는지 체크하는데 count 수가 0이면 ‘해당국가 없음’ 이란 문자열 값을 할당했고, 0이 아니면 다시 국가명을 선택해 vs_country_name 변수에 할당해 반환했다. 위 함수를 다시 실행해 보자.
입력
SELECT fn_get_country_name (52777) COUN1, fn_get_country_name(10000) COUN2
FROM DUAL;
결과
COUN1 COUN2
------------------ ----------------
Denmark 해당국가 없음
원하는 결과가 나오긴 했는데, 사실 이 함수는 필요 없는 로직이 존재한다. 해당 국가가 있는지 체크하기 위해 국가 테이블을 한 번 조회했고, 국가가 있으면 국가명을 가져오기 위해 또 한 번 더 조회한 것이다. 굳이 2번 조회할 필요 없이 한 번만 조회해서 처리해도 될 것 같은데, 이런 식으로 로직을 작성한 이유에 대해서는 다음 장에서 자세히 설명할 것이다.
지금까지 만든 함수는 모두 매개변수가 있었는데 매개변수 없이도 함수를 만들 수 있다. 현재 로그인한 사용자 이름을 반환하는 함수를 만들어 보자.
입력
CREATE OR REPLACE FUNCTION fn_get_user
RETURN VARCHAR2 -- 반환 데이터타입은 VARCHAR2
IS
vs_user_name VARCHAR2(80);
BEGIN
SELECT USER
INTO vs_user_name
FROM DUAL;
RETURN vs_user_name; -- 사용자 이름 반환
END;
결과
FUNCTION FN_GET_USER이(가) 컴파일되었습니다.
위에서 설명했듯이 매개변수가 없으면 함수 이름 다음에 ‘( )’를 붙여도 되고 빼도 된다.
입력
SELECT fn_get_user(),fn_get_user
FROM DUAL;
결과
FN_GET_USER() FN_GET_USER
-------------- -------------------
ORA_USER ORA_USER