참고
쉬운코드: SQL에서 stored function을 아시나요?
쉬운코드: SQL에서 stored procedure를 아시나요
쉬운코드: stored procedure를 백엔드 실무에서 쓰기에 조심스러운 이유
;
를 구분자(delimiter)로 사용한다.;
가 들어가면 문제가 생길 수 도 있다.$$
로 구분자를 변경해 준다.앞자리가 1로 시작하는 4자리의 랜덤 아이디를 만들고 싶다.
delimiter $$
CREATE FUNCTION id_generator() # 함수 시그니처: 이름(파라미터 타입)
RETURNS int # 함수의 리턴 타입
NO SQL # MySQL 특화 문법
BEGIN # Function Body 시작
RETURN (1000 + floor(rand() * 1000));
END $$ # Function Body 끝
delimiter ;
INSERT INTO employee
VALUES (id_generator(), ...); # 생성한 Function을 사용
부서의 Id가 주어지면, 해당 부서 구성원들의 평균 연봉을 알고 싶다.
delimiter $$
CREATE FUNCTION dept_agv_salary(d_id int) # int 타입 파라미터를 사용한다.
RETURNS int # 반환 타입
READS SQL DATA # MySQL 특화 문법
BEGIN # Function Body 시작
DECLARE avg_sal int; # 변수 선언: 변수이름 타입
SELECT AVG(salary) INTO avg_sal
FROM employee
WHERE dept_id = d_id;
RETURN avg_sal;
END $$ # Function Body 끝
delimiter ;
SELECT *, dept_agv_salary(id)
FROM department;
점수가 토익 800점을 넘었는지 확인하고 싶다.
delimiter $$
CREATE FUNCTION pass_validator(score int)
RETRUNS char(4)
NO SQL
BEGIN
DECLARE pass_fail char(4);
IF scroe is null THEN SET pass_fail = 'fail';
ELSEIF score < 800 THEN SET pass_fail = 'fail';
ELSE SET pass_fail = 'true';
END IF;
END $$
delimiter ;
SELECT *, pass_validator(score)
FROM student;
case
를 사용해서 분기 처리 가능# Stored Function 목록 조회
SHOW FUNCTION STATUS
WHERE DB = 'DB_NAME';
# Stored Function 내용 조회
SHOW CREATE FUNCTION function_name;
DROP FUNCTION function_name;
Stored Function
은 단순히 Util 함수 정도로만 사용하는게 좋다.# 1. DECLARE 사용
MySQL은 DECLARE를 통한 변수 선언을 Procedure에서만 사용 가능한 것 같음
# 2. SET 사용
MySQL은 SET을 사용해서 변수를 선언 할 수 있음
SET @변수명 = 초기값;
SET @my_var = 1;
DELIMITER $$
CREATE PROCEDURE product(IN a INT, IN b INT, OUT c INT)
BEGIN
SET c = a * b;
END $$
DELIMITER ;
IN
키워드를 사용해서, 함수에 값을 전달하는 목적의 파라미터임을 나타냄OUT
키워드를 사용해서, 함수의 결과를 반환하는 목적의 파라미터임을 나타냄IN
은 생략 가능 -> 별도로 명시하지 않으면 기본적으로 IN
파라미터로 인식# 변수 선언을 생략하고 바로 사용할 수 있는 것 같음
CALL product(5,4, @result);
SELECT @result;
delimiter $$
CREATE PROCEDURE swap(INOUT a int, INOUT b int)
BEGIN
DECLARE temp int;
SET temp = a;
# 위 두 문장을 'SET @temp = a;'로 축약 가능
SET a = b;
SET b = temp;
END $$
delimiter ;
INOUT
를 사용해서, 파라미터를 값을 전달, 반환하는 목적으로 동시에 사용 가능SET @a = 5;
SET @b = 1;
CALL swap(@a, @b);
SELECT @a, @b; # @a = 1, @b = 5
delimiter $$
CREATE PROCEDURE avg_sal()
BEGIN
SELECT dept_id, avg(salary)
FROM department
GROUP BY dept_id;
END $$
delimiter ;
CALL avg_sal()
새로운 닉네임으로 변경하고, 기존 닉네임을 로깅하고 싶다.
delimiter $$
CREATE PROCEDURE changeAndLog(user_id INT, c VARCHAR(30))
BEGIN
INSERT INTO nickname_log (
SELECT id, nickname, now()
FROM users
WHERE id = user_id
);
UPDATE users
SET nickname = newNickname
WHERE id = user_Id;
END $$
delimiter ;
CALL changeAndLog(1, "newNickname");
# 프로시저 목록 조회
SHOW PROCEDURE STATUS;
# 특정 프로시저 상세 정보
SHOW CREATE PROCEDURE procedure_name;
DROP PROCEDURE procedure_name;
CREATE FUNCTION ...
CREATE PROCEDURE ...
RETURN
키워드로 1개의 값 반환 가능OUT, INOUT
키워드로 파라미터를 통한 여러 값 반환 가능SELECT *, product(price, order_count) FROM Orders;
CALL
키워드를 통한 단독 호출만 가능CALL MyProcedure();