스토어드 프로시저
- MySQL에서 프로그래밍 기능이 필요할 때 사용하는 데이터베이스 개체
DELIMITER $$
CREATE PROCEDURE 스토어드_프로시저_이름()
BEGIN
이 부분에 SQL 프로그래밍 코딩
END $$ -- 스토어드 프로시저 종료
DELIMITER; -- 종료 문자를 다시 세미콜론으로 변경
CALL 스토어드_프로시저_이름(); -- 스토어드 프로시저 실행
1. IF 문
- 기본 형식
IF <조건식> THEN
SQL 문장들
END IF;
- SQL 문장이 두 문장 이상이 처리되어야 할 때는 BEGIN ~ END로 묶어줘야 함
ex)
DROP PROCEDURE IF EXISTS ifProc1; -- 기존에 ifPro1을 만든적이 있다면 삭제
DELIMITER //
CREATE PROCEDURE ifProc1() -- 스토어드 프로시저 이름을 ifProc1()로 설정
BEGIN
IF 100 = 100 THEN
SELECT '100은 100과 같습니다.';
END IF;
END //
DELIMITER ;
CALL ifProc1();
IF ~ ELSE문
USE market_db;
DROP PROCEDURE IF EXISTS ifProc2;
DELIMITER $$
CREATE PROCEDURE ifProc2()
BEGIN
DECLARE myNum INT;-- myNum 변수 선언
SET myNum = 200;
IF myNum = 100 THEN
SELECT '100입니다.';
else
SELECT '100이 아닙니다.';
END IF;
END $$
DELIMITER ;
CALL ifProc2();
1) DECLARE 예약어를 사용해서 myNum 변수 선언
DECLARE myNum INT;
2) SET 예약어로 myNum 변수에 200 대입
SET myNum = 200;
IF문의 활용
- APN (에이핑크)인 회원의 데뷔 일자가 5년이 넘었는지 확인해보고 5년이 넘었으면 축하메시지 출력
USE market_db;
DROP PROCEDURE IF EXISTS ifProc3;
DELIMITER //
CREATE PROCEDURE ifProc3()
BEGIN
DECLARE debutDate DATE; -- 데뷔일자
DECLARE curDate DATE; -- 오늘
DECLARE days INT; -- 활동한 일수
SELECT debut_date INTO debutDate
FROM market_db.member
WHERE mem_id = 'APN';
SET curDate = CURRENT_DATE(); -- 현재 날짜
SET days = DATEDIFF(curDate, debutDate);
IF(days/365) >=5 TEHN -- 5년이 지났다면
SELECT '데뷔한 지' + days + '일이나 지났습니다.';
ELSE
SELECT '데뷔한 지' + days + '일밖에 안되었네요.';
END IF;
END //
DELIMITER ;
CALL ifProc3();
1) SELECT ~ INTO
- 결과를 변수에 저장
- 에이핑크의 데뷔 일자가 debutDate에 저장
SELECT debut_date INTO debutDate
FROM market_db.member
WHERE mem_id = 'APN';
날짜 관련 함수
- CURRENT_DATE() : 오늘 날짜를 알려줌
- CURRNET_TIMESTAMP() : 오늘 날짜 및 시간을 함께 알려줌
- DATEDIFF(날짜1, 날짜2) : 날짜2부터 날짜1까지 일수로 몇일인지 알려줌
2. CASE문
-기본 형식
CASE
WHEN 조건 1 THEN
SQL 문장1
WHEN 조건 2 THEN
SQL 문장2
WHEN 조건 3 THEN
SQL 문장3
ELSE
SQL 문장4
END CASE;
- 활용
회원들의 총 구매액을 계산해서 회원의 등급을 4단계로 나눔
1) 구매 테이블에서 회원의 아이디(mem_id)별로 가격과 수량을 곱해서 총 구매액의 합계 구하기
SELECT mem_id, SUM(price*amount) "총구매액"
FROM buy
GROUP BY mem_id;
2) 모든 회원의 아이디와 이름 출력 (외부 조인 이용)
SELECT M.mem_id, M.mem_name,
SUM(price*amount) "총구매액"
FROM buy B
RIGHT OUTER JOIN member M
ON B.mem_id = M.mem_id
GROUP BY M.mem_id
ORDER BY SUM(price*amount) DESC;
3) 총 구매엑에 따라 회원 등급 구분
CASE
WHEN (총구매액 >= 1500) THEN '최우수 고객'
WHEN (총구매액 >= 1000) THEN '우수 고객'
WHEN (총구매액 >= 1) THEN '일반 고객'
ELSE '유령 고객'
END
4) CASE문을 새로운 열로 추가
-> 새로운 '회원등급'열이 추가되고 총 구매액에 따라서 회원이 분류됨
SELECT M.mem_id, M.mem_name, SUM(price*amount) "총구매액",
CASE
WHEN (SUM(price*amount) >= 1500) THEN '최우수 고객'
WHEN (SUM(price*amount) >= 1000) THEN '우수 고객'
WHEN (SUM(price*amount) >= 1) THEN '일반 고객'
ELSE '유령 고객'
END "회원등급"
FROM buy B
RIGHT OUTER JOIN member M
ON B.mem_id = M.mem_id
GROUP BY M.mem_id
ORDER BY SUM(price*amount) DESC;
3. WHILE 문
- 기본 형식
WHILE <조건식> DO
SQL 문장들
END WHILE;
- ITERATE [레이블]
- 지정한 레이블로 가서 계속 진행
- continue 역할
-LEAVE [레이블]
- 지정한 레이블을 빠져나감.
- WHILE문이 종료됨
- break 역할
- 활용
1에서 100까지 합계에서 4의 배수를 제외
USE market_db;
DROP PROCEDURE IF EXISTS whileProc;
DELIMITER $$
CREATE PROCEDURE whileProc()
BEGIN
DECLARE i INT; -- 1에서 100까지 증가할 변수
DECLARE hap INT; -- 더한 값을 누적할 변수
SET i=1;
SET hap = 0 ;
myWhile: -- WHILE문을 myWhile이라는 레이블로 지정
WHILE (i <= 100) DO
IF (i%4 = 0) THEN
SET i=i+1;
ITERATE myWhile; -- 지정한 레이블문으로 가서 계속 진행
END IF;
SET hap = hap + i; -- 4의 배수가 아니면 hap에 누적
IF(hap > 1000) THEN
LEAVE myWhile; -- 지정한 레이블문을 떠남
END IF;
SET i=i+1;
END WHILE;
SELECT '1부터 100까지의 합 (4의 배수 제외), 1000 넘으면 종료 =>', hap;
END $$
DELIMITER ;
CALL whileProc();
4. 동적 SQL
- 상황에 따라 내용 변경이 필요할 때 동적 SQL을 사용하면 변경되는 내용을 실시간으로 적용시켜 사용 가능
PREPARE
- SQL 문을 실행하지 않고 미리 준비 해둠
EXECUTE
- 준비한 SQL문을 실행
DEALLOCATE PREPARE
- 실행 후에는 문장을 해제
- PREPARE문에서는 ?로 향후에 입력될 값을 비워놓고, EXECUTE에서 USING으로 ?값에 전달 가능
ex)
보안이 중요한 출입문에서는 출입할 내역을 테이블에 기록
출입증을 태그한느 순간의 날짜와 시간이 INSERT문으로 만들어져서 입력되도록
DROP TABLE IF EXISTS gate_table;
CREATE TABLE gate_table (id INT AUTO_INCREMENT PRIMARY KEY, entry_time DATETIME); -- 출입용 테이블 작성
SET @curDate = CURRENT_TIMESTAMP(); -- 현재 날짜와 시간
PREPARE myQuery FROM 'INSERT INTO gate_table VALUES(NULL,?)'; -- ?를 사용해서 entry_time에 입력할 값을 비워놓음
EXECUTE myQuery USING @curDate;
DEALLOCATE PREPARE myQuery;
SELECT * FROM gate_table;
'데이터 > SQL' 카테고리의 다른 글
[혼공] 5-3장 가상의 테이블 뷰 (0) | 2023.08.13 |
---|---|
[혼공] 5-2장 테이블 제약조건 (0) | 2023.08.13 |
[혼공] 4-2장 두 테이블을 묶는 조인 (0) | 2023.08.08 |
[혼공] 4-1장 MySQL의 데이터 형식 (0) | 2023.08.07 |
[혼공] 3-3장 데이터 변경을 위한 SQL문 (0) | 2023.08.07 |