728x90
서론
스토어드 프로시저
스토어드 프로시저는 MySQL에서 프로그래밍 기능이 필요할 때 사용하는 데이터베이스 개체이다.
SQL 프로그래밍은 기본적으로 스토어드 프로시저 안에 만들어야한다.
-- 스토어드 프로시저 코딩 시작
DELIMITER $$
CREATE PROCEDURE 스토어드 프로시저 이름()
BEGIN
-- 이 부분에 sql 프로그래밍 코딩
END $$
-- 스토어드 프로시저 코딩 끝
DELIMITER; -- 종료문자를 다시 세머콜론으로 변경
CALL 스토어드 프로시저 이름(); -- 스토어드 프로시저 실행
IF문
IF문은 조건문으로 가장 많이 사용되는 프로그래밍 문법 중 하나입니다.
참 혹은 거짓만 있기 때문에 2중 분기 입니다.
기본 형식
if <조건식> then
sql 문장들
end if;
SQL의 문장들이 두문장 이상이라면 begin ~ end로 묶어야합니다. 현재는 한문장이더라도 나중에 추가될 수 있으니 꼭 이렇게 묶는 습관을 들여야합니다.
drop procedure if exists ifProc1; -- 1
delimiter $$ -- 2
create procedure ifProc1() -- 3
begin
if 100 = 100 then -- 4
select '100은 100과 같습니다.';
end if; -- 4
end $$ -- 2
delimiter ;
call ifProc1(); -- 5
- 만약 기존에 ifProc1() 을 만든적이 있다면 삭제합니다.
- 세미콜론으로는 SQL의 끝인지, 스토어드 프로시저의 끝인지 구별할 수 없어서 $$을 사용합니다.
- 스토어드 프로시저의 이름을 ifProc1()으로 지정합니다
- 조건식으로 100과 100이 같은지 비교합니다. 참이라면 다음 행이 실행됩니다.
- call로호출하면 ifProc1()이 실행됩니다.
IF ~ ELSE 문
drop procedure if exists ifPorc2;
delimiter $$
create procedure ifProc2()
begin
declare myNum int; -- 1
set myNum == 200; -- 2
if myNum = 100 then --3
select '100입니다.';
else
select '100이 아닙니다.';
end if; -- 3
end $$
delimeter ;
call ifProc2();
- declare 예약어를 사용해서 myNum 변수를 신언했습니다. 제일 뒤에는 변수의 데이터 형식을 int로 지정했습니다.
- set 예약어로 myNum 변수에 200을 대입했습니다.
- myNum이 100인지 아닌지 구분합니다.
IF 문의 활용
아이디가 APN인 회원의 데뷔일자가 5년이 넘었는지 확인해보고 5년이 넘었으면 축하 메시지를 출력해보자
drop procedure if exists ifProc3;
delimiter $$
create procedure ifProc3()
begin
-- 1. 변수 생성
declare debutDate DATE; -- 데뷔일자
declare curDate DATE; -- 오늘
declare days INT; -- 활동한 일수
-- 2. 변수 값 할당
select debute_date into debutDate
from market_db.member
where mem_id = 'APN';
-- 3. 날짜 저장
set curDate = current_date(); -- 현재날짜
-- 4. 날짜 차이 저장
set days = datediff(curDate, devbutDate); -- 날짜의 차이, 일 단위
if (days/365) >= 5 then -- 5년이 지났다면
select concat('데뷔한 지' , days , '일이나 지났습니다. 축하합니다!');
else
select '데뷔한 지' + days + '일 밖에 안되었네요,. 화이팅!';
end if;
end $$
delimiter ;
call ifProc3();
- 변수를 세개 만들었습니다.
- APN이라는 커럶의 debute_date 라는 컬럼의 값들을 debutDate에 할당했습니다.
- 현재 날짜를 curDate에 저장했습니다.
- 현재 날짜에서 데뷔 날짜를 뺀 값을 datediff 함수를 사용하여 days에 저장했습니다.
CASE 문
여러 조건 중에서 선택해야 하는 경우 사용합니다.
여러가지 조건이 있기 때문에 다중 분기라고 부릅니다.
기본형식
case
when 조건1 then
--
when 조건2 then
--
when 조건3 then
--
Else
end case;
활용
시험 성적 90점 이상은 A, 80점 이상은 B, 70점 이상은 C, 60점 이상은 D, 60점 미만은 F
drop procedure if exists caseProc;
delimiter $$
create procedure caseProc()
begin
declare point int;
declare credit chaar(1);
declare point = 88;
case
when point >= 90 then
set credit = 'A';
when point >= 80 then
set credit = 'B';
when point >= 70 then
set credit = 'C';
when point >= 60 then
set credit = 'D';
else
set credit = 'F';
end case;
select concat('취득 점수 ==> ', point), concat('학점 ==>', credit);
end $$
delimiter ;
call caseProc();
활용2(중요함)
총 구매액 | 회원등급 |
1500 이상 | 최우수고객 |
1000 ~ 1499 | 우수고객 |
1 ~ 999 | 일반고객 |
0 이하(구매한 적 없음) | 유령고객 |
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.member_id = m.member_id
group by m.mem_id
order by sum(price*amount) desc;
WHILE 문
필요한 만큼 계속 같은 내용을 반복가능
기본 형식
while <조건식> do
sql 문장들
end while
활용
1에서 100까지 모두 더하는 기능
drop procedure if exists whileProc;
delimiter $$
create procedure whileProc()
begin
declare i int;
declare hap int;
set i = 1;
set hap = 0;
while(i <= 100) do
set hap = hap + i;
set i = i + 1;
end while;
select hap;
end $$
delimiter ;
call whileProc();
응용
1에서 100까지의 합계에서 4의 배수를 제외하려면? 추가로 숫자를 더하는 중간에 합계가 1000이 넘으면 더하는 것을 그만두고 1000이 넘는 순간의 숫자를 출력한 후 프로그램을 종료하고 싶을때
이럴때는 iterate문과 leave문을 활용할 수 있다.
- iterate : 지정한 레이블로 가서 계속 진행
- leave : 지정한 레이블을 빠져나감 즉 while문이 종료됨
drop procedure if exists whileProc2;
delimiter $$
create procedure whilePric2()
begin
declare i int;
declare hap int;
set i = 1;
set hap = 0;
mywhile;
while(i <= 100) do
if(1 % 4 = 0) then
set i = i + 1;
iterate myWhile;
end if;
set hap = hap + i;
if (hap > 1000) then
leave myWhile;
end if;
set i = i + 1;
end while;
select hap;
end $$
delimiter ;
call whileProc2();
동적 SQL
상황에 따라서 내용의 변경이 필요할때 사용한다.
prepare 와 excute
쿼리문을 실행하지는 않고 미리 준비만 해놓은 상태에서 excute로 실행한다. 실행한 후에는 deallocate prepare로 문장을 해제해주는 것이 바람직하다.
예제
use market_db;
prepare myQuery from 'select * from member where mem_id = "BLK";
execute myQuery;
deallocate prepare myQuery;
동적 SQL의 활용
gate_table에 entry_time을 비워놓고 나중에 넣기
drop table if exists gate_table;
create table gate_table (id int auto_increament primary key, entry_time datetime)
set @curDate = current_timestamp();
prepare myQuery from 'insert into gate_table values(null, ?)';
execute myQuery using @curDate;
deallocate prepare myQuery;
select * from gate_table
반응형
'데이터' 카테고리의 다른 글
두 테이블을 묶는 조인 (0) | 2024.01.22 |
---|---|
MySQL 데이터 형식 (0) | 2024.01.20 |
데이터 변경을 위한 sql문 (0) | 2024.01.18 |
깊게 알아보는 select 문 (0) | 2024.01.16 |
SELECT-FROM-WHERE (0) | 2024.01.09 |