SQL

[MySQL] 7. FUNCTION

찰리-누나 2022. 12. 26.

 

 

 


FUNCTION


SQL에는 프로시저와 비슷한 기능으로 FUNCTION이라는 것이 존재한다. 직역하면 '함수'라는 뜻인데, js에서의 function과 같은 역할을 한다. 프로시저가 자주 사용되는 쿼리문을 작성하는 함수라면, Function은 자주 사용되는 계산식을 작성해 재사용하는 함수이다. 

 

Function은 프로시저와 다르게 CALL 없이 함수이름(파라미터);로 호출하여 바로 사용할 수 있다. RETURN문을 사용해 반환할 값을 지정해 줄 수 있으며, 이때 RETURN 할 값의 타입을 RETURNS 옆에 기재해 주어야 한다.

 

Function을 작성할 때 필요한 데이터 특성 옵션으로는 DETERMINISTIC, NO SQL, READS SQL DATA, MODIFIES SQL DATA 이 있는데 공식 문서에 따르면 아래와 같다.

https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html

 

MySQL :: MySQL 8.0 Reference Manual :: 13.1.17 CREATE PROCEDURE and CREATE FUNCTION Statements

13.1.17 CREATE PROCEDURE and CREATE FUNCTION Statements CREATE [DEFINER = user] PROCEDURE [IF NOT EXISTS] sp_name ([proc_parameter[,...]]) [characteristic ...] routine_body CREATE [DEFINER = user] FUNCTION [IF NOT EXISTS] sp_name ([func_parameter[,...]])

dev.mysql.com

 

  • DETERMINISTIC : 항상 같은 값을 리턴할 경우
  • NO SQL : 루틴에 SQL문이 포함되지 않을 경우
  • READS SQL DATA : SELECT문을 사용할 경우
  • MODIFIES SQL DATA : INSERT, DELETE문을 사용할 경우

 

만일 이 키워드를 작성하지 않으면 아래 오류가 출현한다. 이번 실습에서는 항상 같은 계산을 실행할 것이므로, DETERMINISTIC를 작성해 주었다.

ERROR 1418 (HY000) : This function hasn none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

 


 

 

실습을 위해 user에 point라는 컬럼을 추가해주고, 값을 넣어주었다.

ALTER TABLE chalishop.`user` ADD `point` INT NULL;

 

GUI를 사용해 Function을 작성해 본다. 프로시저와 똑같이 BEGINT과 END 사이에 수행할 문장을 적어주면 되는데, RETURNS 옆에 리턴값의 타입을 반드시 명시해 주어야 한다. 입력된 point의 값에 숫자 500을 더해주는 함수를 작성하였다. 

보너스로 500포인트를 유저에게 입금하는 Function을 작성하고 사용해본다.

 

SQL 쿼리문으로 함수를 작성할 때에는 프로시저를 작성할 때와 같이 DELIMITER 이 포함되어야 한다.

DELIMITER $$
CREATE FUNCTION DB이름.함수이름(파라미터 INT)
    RETURNS 리턴타입
    DETERMINISTIC
BEGIN
    RETURN 리턴할값;
END
$$
DELIMITER ;

 

다시 500원을 빼앗는 Function을 작성하고 사용해 보았다.

 

MySQL의 function 안에서  SELECT INTO는 사용이 가능하지만, 쿼리를 조회하기만 하는 SELECT문의 사용은 불가능하다. 또한 MySQL에서 IF ELSE문은 프로시저에만 사용할 수 있다. BEGIN과 END 안에 IF문을 넣어 사용하기만 하면 되는거라, 프로시저때 실습해 보았으니 패스한다.

댓글