MYSQL을 사용시에 동적으로 sql 문을 생성하려 할때 아래와 같은 형태로 Prepare 구문을 사용합니다.
PREPARE stmt_name FROM preparable_stmt
EXECUTE stmt_name [USING @var_name [, @var_name] ...]
{DEALLOCATE | DROP} PREPARE stmt_name
Prepare 구문에 대한 자세한 내용은 아래 링크 페이지를 참조하세요.
참고 링크 : Prepared 문을 위한 SQL 신텍스
사용자 정의 변수(@변수명) 을 sql 구문으로 만드는 문자열 안에 그대로 넣어서 편하게 사용 할수가 있습니다.
이 때 주의할 점에 대해 아래 코드의 주석에 기술 되어 있으니 참고 하면 될 것 같습니다.
-- CREATE TEST TABLE DROP TABLE IF EXISTS TB_AGENCY; CREATE TABLE TB_AGENCY ( ID TINYINT(4) NOT NULL COMMENT '통신사 ID (0-SKT, 1-KTF, 2-LG, 3-기타)' , NAME VARCHAR(20) NOT NULL COMMENT '통신사 이름' , PRIMARY KEY (ID) , UNIQUE KEY IDX_TB_AGENCY_NAME (NAME) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO TB_AGENCY() VALUES (1, 'SKT'), (2, 'KTF'), (3, 'LGU'), (4, 'ETC'); -- CREATE TEST FUNCTION DROP FUNCTION IF EXISTS FN_PREPARE_STMT_CONDITION_PREFIX; DELIMITER $$ CREATE FUNCTION FN_PREPARE_STMT_CONDITION_PREFIX ( IN_CONDITION_CNT INT ) RETURNS VARCHAR(10) CHARSET utf8 ROOT_FN : BEGIN IF IN_CONDITION_CNT > 0 THEN RETURN ' WHERE '; ELSE RETURN ' AND '; END IF; END ROOT_FN $$ DELIMITER ; -- CREATE TEST PROCEDURE DROP PROCEDURE IF EXISTS PR_TEST; DELIMITER $$ CREATE PROCEDURE PR_TEST ( IN_ID TINYINT(4) , IN_NAME VARCHAR(20) , IN_LIMIT_OFFSET INT , IN_LIMIT_CNT INT , OUT O_CNT INT ) ROOT_PR : BEGIN DECLARE CONDITION_CNT INT DEFAULT 0; DECLARE CONTINUE HANDLER FOR NOT FOUND BEGIN SET @O_CNT = 0; END; SET @IN_ID = IN_ID; -- 사용자 정의 변수 초기화 SET @IN_NAME = IN_NAME; -- 사용자 정의 변수 초기화 SET @IN_LIMIT_OFFSET = IN_LIMIT_OFFSET; -- 사용자 정의 변수 초기화 SET @IN_LIMIT_CNT = IN_LIMIT_CNT; -- 사용자 정의 변수 초기화 SET @O_CNT = 0; -- 사용자 정의 변수 초기화 SET @SQL_QUERY_1 = "SELECT * FROM TB_AGENCY "; -- Prepare Statements 구문의 변수가 삽입될 부분에 사용자 변수를 그대로 사용 : INTO @O_CNT SET @SQL_QUERY_2 = "SELECT COUNT(*) INTO @O_CNT FROM TB_AGENCY "; SET @SQL_WHERE = ''; IF @IN_ID > 0 THEN SET CONDITION_CNT := CONDITION_CNT + 1; SET @SQL_WHERE= CONCAT(@SQL_WHERE, FN_PREPARE_STMT_CONDITION_PREFIX(CONDITION_CNT), " ID > @IN_ID "); END IF; IF @IN_NAME !='' THEN SET CONDITION_CNT := CONDITION_CNT + 1; -- Prepare Statements 구문의 LIKE 같은경우 '' 안에서 사용자 변수값을 적어주어야 하는데 -- SET @SQL_WHERE = CONCAT(@SQL_WHERE, " AND LOWER(NAME) LIKE ''%@IN_NAME%'' "); -- 위와 같이 적을 경우 syntax 오류가 발생하기 때문에 아래와 같이 사용 SET @IN_NAME = CONCAT("%", LOWER(@IN_NAME), "%"); SET @SQL_WHERE = CONCAT(@SQL_WHERE, FN_PREPARE_STMT_CONDITION_PREFIX(CONDITION_CNT), " LOWER(NAME) LIKE @IN_NAME "); END IF; -- Prepare Statements 구문의 LIMIT 에 사용자 변수를 그대로 사용할 경우 인지를 하지 못하므로 문자열로 연결 SET @SQL_ORDER = CONCAT(" ORDER BY ID ASC LIMIT ", @IN_LIMIT_OFFSET , ",", @IN_LIMIT_CNT); SET @SQL_QUERY_1 = CONCAT(@SQL_QUERY_1, @SQL_WHERE, @SQL_ORDER); PREPARE STATEMENTS FROM @SQL_QUERY_1; EXECUTE STATEMENTS; DEALLOCATE PREPARE STATEMENTS; SET @SQL_QUERY_2 = CONCAT(@SQL_QUERY_2, @SQL_WHERE, @SQL_ORDER); PREPARE STATEMENTS FROM @SQL_QUERY_2; EXECUTE STATEMENTS; DEALLOCATE PREPARE STATEMENTS; -- OUT 변수인 O_CNT에 사용자 정의변수에 담긴 값을 설정 SET O_CNT = @O_CNT; END ROOT_PR $$ DELIMITER ; CALL PR_TEST('0', 'K', 0, 2, @O_CNT); SELECT @O_CNT;
'Database > MYSQL' 카테고리의 다른 글
[MySQL] SQL_MODE | Eclipse에서 Toad Plugin 사용시에 세션의 SQL_MODE를 서버의 SQL_MODE와 동일하게 적용 (0) | 2015.07.17 |
---|
댓글