MySQL에서는 테이블 이름을 저장 프로시저의 매개변수로 전달하여 해당 테이블의 모든 레코드를 동적으로 조회할 수 있습니다. 이를 위해서는 동적 SQL(Dynamic SQL) 기법, 즉 PREPARE 문과 EXECUTE 문을 활용해야 합니다.
저장 프로시저 생성하기
다음 예제는 테이블 이름을 매개변수로 받아 해당 테이블의 전체 레코드를 출력하는 'details'라는 프로시저를 생성합니다.
mysql> DELIMITER //
mysql> Create procedure details(tab_name Varchar(40))
-> BEGIN
-> SET @t:= CONCAT('Select * from',' ',tab_name);
-> Prepare stmt FROM @t;
-> EXECUTE stmt;
-> END //
Query OK, 0 rows affected (0.00 sec)
프로시저의 작동 원리
- CONCAT 함수: 매개변수로 받은 테이블 이름과 SELECT 쿼리 문자열을 하나로 합쳐 완전한 SQL 문장을 만듭니다.
- PREPARE 문: 생성된 SQL 문자열을 서버에서 실행 가능한 형태로 준비(prepare)합니다.
- EXECUTE 문: 준비된 문장을 실제로 실행하여 결과를 반환합니다.
프로시저 호출하기
이제 CALL 명령으로 프로시저를 호출하면서 테이블 이름을 인자로 넘기면, 해당 테이블의 모든 레코드가 화면에 출력됩니다.
mysql> DELIMITER;
mysql> CALL details('student_detail');
+-----------+-------------+------------+
| Studentid | StudentName | address |
+-----------+-------------+------------+
| 100 | Gaurav | Delhi |
| 101 | Raman | Shimla |
| 103 | Rahul | Jaipur |
| 104 | Ram | Chandigarh |
| 105 | Mohan | Chandigarh |
+-----------+-------------+------------+
5 rows in set (0.02 sec)
Query OK, 0 rows affected (0.03 sec)
주의 사항
테이블 이름처럼 식별자(identifier)는 일반적인 바인드 파라미터(?)로 전달할 수 없기 때문에 위와 같은 동적 SQL 방식이 필요합니다. 다만 이 방식은 SQL 인젝션(SQL Injection)에 노출될 위험이 있으므로, 실무 환경에서는 외부 입력값을 그대로 사용하지 말고 반드시 입력값 검증 또는 화이트리스트 방식으로 허용된 테이블 이름만 사용하는 것이 안전합니다.