출처1 https://mariadb.com/kb/en/library/find_in_set/:
출처2 : https://stackoverflow.com/questions/13809101/mysql-dynamic-in-clause-from-a-split-on-a-string
2018/07/24 - [프로그램 자료/MySQL & MariaDB] - [MySQL & MariaDB] 동적 프로시저 dynamic procedure
[개발환경]
MariaDB 10.0
개발작업을 하다보면 특히 조회동작시에 동적쿼리를 생각보다 많이 사용하게 된다.
개중엔 웹화면에서 checkbox로 작업하여 선택한 것들만 조회되도록 하는 경우도 있는데,
mysql/mariadb 에서는 find_in_set 함수를 사용하여 구현할 수 있다.
우선 find_in_set 함수가 무슨 일을 하는지 알아야 할 것 같다.
아래와 같은 쿼리를 실행하면 #(주석) 이후에 있는 출력값을 주어진다.
set @clause = 'A,B,C';
select find_in_set('A', @clause); # 1
select find_in_set('B', @clause); # 2
select find_in_set('C', @clause); # 3
select find_in_set('D', @clause); # 0
'A,B,C' 라는 문자열을 comma(,)로 자른 배열을 생성하고 거기에서 equal(=)로 검색하여 index를 반환한다.
이걸 사용해서 in clause 동작을 하도록 할 수 있다.
주의할 점은 콤마 사이에 공백이 있다면 해당 칼럼에서 조회된 값에도 공백이 있어야 검색이 된다는 점이다.
set @clause = 'A,B,C';
select t.*
from table as t
where find_in_set(t.tpye, @clause ) > 0;
프로시저에서는 다음과 같이 사용가능하다.
DELIMITER $$
USE `dbname`$$
DROP PROCEDURE IF EXISTS usp_test$$
CREATE DEFINER=`userid`@`%` PROCEDURE `usp_test`(
IN `logTypeCode` varchar(20)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT '로그 조회 테스트'
BEGIN
if (logTypeCode is null OR logTypeCode = '') then
SET @logTypeCode := 'A,B,C';
else
SET @logTypeCode := logTypeCode;
end if;
SET @Sql = "";
SET @Sql = CONCAT(@Sql, CHAR(10),"select l.*");
SET @Sql = CONCAT(@Sql, CHAR(10),"from log_table as l");
SET @Sql = CONCAT(@Sql, CHAR(10),"where 1=1 ");
SET @Sql = CONCAT(@Sql, CHAR(10)," and (find_in_set(l.logtype, ? ) > 0)");
PREPARE dquery FROM @Sql;
EXECUTE dquery USING @logTypeCode;
END$$
DELIMITER ;