1. 데이터베이스 프로그래밍의 개념
- 프로그래밍
- 프로그램을 설계하고 소스 코드를 작성하여 디버깅하는 과정
- 데이터베이스 프로그래밍
- DBMS에 데이터를 정의하고 저장된 데이터를 읽어와 데이터를 변경하는 프로그램을 작성하는 과정
- 데이터베이스 언어인 SQL을 포함한다는 점이 일반 프로그래밍과 다름
- 데이터베이스 프로그래밍 방법
- SQL 전용 언어 사용하기
- SQL 자체의 기능을 확장하여 변수, 제어, 입출력 등의 기능을 추가한 새로운 언어를 사용함.
- MySQL : 저장 프로그램
- 오라클: PL/SQL
- SQL Server : T-SQL
- 일반 프로그래밍 언어에 SQL을 삽입하여 사용하기
- C, C++, Java, Python 등 일반 프로그래밍 언어에 SQL을 삽입하여 사용함
- 삽입된 SQL문은 DBMS 컴파일러가 처리함
- 웹 프로그래밍 언어에 SQL을 삽입하여 사용하기
- JSP, PHP, ASP 등의 웹 스크립트 언어나 Django, Flask, Spring 등의 웹 프레임워크에 SQL을 삽입하여 사용함
- 4GL
- 데이터베이스 관리 기능과 비주얼 프로그래밍 기능을 갖춘 ‘GUI 기반 소프트웨어 개발 도구’를 사용하여 프로그래밍
- 4GL : Delphi, Power Builder, Visual Basic 등
- 데이터베이스 응용 시스템을 ‘하드웨어-운영체제-DBMS-프로그램 환경’으로 계층화하고 층간의 관계를 표현한 것


2. 저장 프로그램
2-1. 저장 프로그램
- 저장 프로그램은 프로그램 로직을 프로시저로 구현하여 객체 형태로 사용
- CREATE PROCEDURE 문을 사용하여 정의
- 프로시저는 선언부와 실행부(BEGIN-END)로 구성됨
- 선언부에서는 변수와 매개변수를 선언하고 실행부에서는 프로그램 로직을 구현
- 매개변수: 저장 프로시저가 호출될 때 그 프로시저에 전달되는 값
- 변수: 저장 프로시저나 트리거 내에서 사용되는 값
- 소스 코드에 대한 설명문은
/*와*/ 사이, -- 다음에 기술
- 제어문 사용 가능

- DELIMITER 뒤에 오는 기호는 자유롭게 정할 수 있음 (예. $$, //, ### 등)
delimiter $$
CREATE PROCEDURE HelloWorld()
BEGIN
SELECT 'Hello, World!' AS message;
END $$
delimiter ;
CALL HelloWorld();

- 참고) delimiter와 같은 줄에 주석 달면 에러남
CREATE TABLE person (
id INT PRIMARY KEY,
이름 VARCHAR(50),
나이 INT
);
INSERT INTO person(id, 이름, 나이) VALUES
(1, '짱구', 5),
(2, '흰둥이', 30),
(3, '봉미선', 35);
delimiter $$
CREATE PROCEDURE getAge(
IN p_id INT,
OUT p_name VARCHAR(50),
OUT p_age INT
)
BEGIN
SELECT 이름, 나이 INTO p_name, p_age
FROM person
WHERE id=p_id;
END $$
delimiter ;
CALL getAge(2, @NAME, @age);
SELECT @NAME, @age;

2-2. 트리거 실습
- person 테이블에 새로운 행이 삽입될 때, 같은 이름이 이미 존재하면 로그 테이블에 기록하는 트리거
CREATE TABLE person_alert (
alert_id INT AUTO_INCREMENT PRIMARY KEY,
이름 VARCHAR(50),
action_time DATETIME,
message VARCHAR(255)
);
DELIMITER $$
CREATE TRIGGER check_duplicate_name
BEFORE INSERT ON person
FOR EACH ROW
BEGIN
DECLARE cnt INT;
SELECT COUNT(*) INTO cnt
FROM person
WHERE 이름=NEW.이름;
IF cnt>0 THEN
INSERT INTO person_alert(이름,action_time,message)
VALUES(NEW.이름, NOW(), '동명이인');
END IF;
END $$
DELIMITER ;
insert into person(id, 이름, 나이) values (4, '짱구', 7);
select * from person_alert;

2-3. 사용자 정의 함수
- 개발자가 직접 작성하여 SQL 내에서 호출할 수 있는 함수
- 기본 제공 함수로 해결하기 어려운 로직을 캡슐화할 때 유용
- SQL에서 자주 쓰는 계산이나 로직을 "내가 만든 함수"로 등록해두고 필요할 때 호출
- 종류
- 스칼라 함수: MySQL에서 일반적
- 테이블 반환 함수
- 인라인 함수
- 장점
- SQL 코드 간결화
- 유지보수 용이
- 재사용성 증가
- 단점
delimiter $$
create function fnHello()
returns varchar(20)
DETERMINISTIC
begin
return 'Hello World';
end $$
delimiter ;
select fnHello() as message;

delimiter $$
create function fnGetAge(birthdate DATE)
returns int
deterministic
begin
declare age int;
return timestampdiff(year, birthdate, curdate());
end $$
delimiter ;
select fnGetAge('1990-05-15') as age;

2-4. 저장 프로그램 정리
- 프로시저
- 목적: 복잡한 SQL 쿼리와 제어문의 비즈니스 로직을 하나로 묶어서 데이터베이스 서버에 미리 저장해 두고, 필요할 때 이름만 불러서 실행하기 위함
- 주요 활용: 여러 SQL문의 묶음으로 단순 반복 업무에 권장
- 특장점
- 장점: 복잡한 로직을 DB에 몰아넣지 않는다
- 단점: 비즈니스 로직이 DB에 묶이게 되어 버전 관리와 디버깅이 매우 어려움
- 트리거
- 목적: 특정 이벤트가 발생할 때 자동 실행하기 위함
- 주요 활용
- 특장점
- 장점: 백엔드 코드에서 로그 남기는 코드를 누락하더라도, DB 단에서 무조건 실행되므로 데이터의 정확성을 보장
- 단점: 디버깅, 예측 불가능한 성능 저하 문제가 있음
- 사용자 정의 함수
- 특징: 입력을 받아 단일값 또는 테이블 리턴
- 목적: 기본적으로 제공되는 내장 함수로는 해결하기 어려운 로직을 캡슐화하여, 쿼리문 안에서 재사용하기 위함
- 주요 활용
- 데이터 포맷팅(ex. 전화번호 가운데 자리 * 마스킹)
- 반복되는 단일 계산(ex. 생년월일을 입력받아 현재 날짜 기준의 만 나이 계산)
- 특장점
- 장점: 코드 간결화로 가독성 증가
- 단점: 복잡한 연산을 함수로 감싸면 쿼리 최적화를 방해할 수 있음
⇒ 모두 편리한 도구지만, 남용하면 성능 저하와 유지보수 문제를 불러올 수 있음

저장 프로그램 현업 사용 사례
- 프로시저: 디버깅과 장애 발생 가능성의 단점 + 현대 백엔드 개발에서는 비즈니스 로직을 서버에 두는 것을 선호 → 잘 사용하지 않는다.
- 트리거: 회사 직원의 연봉, 비밀번호 등이 변경될 때 로그를 남겨야 할 때
- 사용자 정의 함수: 개인정보 마스킹 및 표준화 규칙 적용
3. 데이터베이스 연동 프로그래밍
