[mariaDB] Procedure , Function create ์ค์ต ๊ธฐ๋ก
1. ์ธ์ฌ๋ง์คํฐ์ 1:1 mapping๋๋ ์ฌ๋ด๋์ถ์์ฅ ๊ธฐ์ด๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๋ ํ๋ก์์ ๋ฅผ ์์ฑํด๋ณด์
USE OSS;
#์ง์ ์ ์ํ์ก ์ถ๊ฐ
ALTER TABLE TB_LOAN ADD COLUMN MONTH_PAY NUMERIC(10) NOT NULL;
#์ปฌ๋ผ ์์น ์ด๋
ALTER TABLE TB_LOAN MODIFY MONTH_PAY NUMERIC(10) AFTER LOAN_AMOUNT;
ALTER TABLE TB_LOAN MODIFY BALANCE NUMERIC(10) AFTER TOTAL_PAY;
SELECT * FROM TB_LOAN;
DELIMITER $$
CREATE OR REPLACE PROCEDURE INSERT_LOAN(OUT v_result INT)
/*
@DESCRIPTION
LOAN ๋ฐ์ดํฐ(๋์ถ ์์ฅ)๋ฅผ ์ฌ์ ์ ๋งํผ ์ธ์ํธ ํ๋ค.
@RETURN
RESULT : ์คํจ(-1) ์ฑ๊ณต(0)
*/
BEGIN
DECLARE v_emp_cnt INT; #์ฌ์ ์
DECLARE v_kor_nm NVARCHAR(10); #์ฌ์๋ช
DECLARE v_min_emp_no INT; #์ฌ์ ๋ฒํธ(min)
DECLARE v_loan_amount INT; #๋์ถ๊ธ์ก
DECLARE v_total_pay INT; #์ด ์ํ์ก
DECLARE v_interest INT; #์ ์ ์ฉ์ด์
DECLARE v_balance INT; #๋์ถ ์์ก
DECLARE v_month_pay INT; #์ ์ํ์ก(๋งค ์ ๊ณ ์ )
DECLARE i INT DEFAULT 0; #Loop i ๋ณ์
DECLARE EXIT HANDLER FOR SQLEXCEPTION #SQL ERROR์ ROLLBACKํ๊ณ v_result -1 ์ฒ๋ฆฌ
BEGIN
ROLLBACK;
SET v_result = -1;
END;
/** ํธ๋์ญ์
์์ */
START TRANSACTION;
SELECT COUNT(*) INTO v_emp_cnt FROM TB_EMP_MST;
SELECT MIN(EMP_NO) INTO v_min_emp_no FROM TB_EMP_MST;
/** ์ฌ์ ์ ๋งํผ Loop */
WHILE i < v_emp_cnt DO
BEGIN
BEGIN
SELECT KOR_NM INTO v_kor_nm FROM TB_EMP_MST WHERE EMP_NO = v_min_emp_no + i;
END;
BEGIN
SELECT RPAD(FLOOR(1 + RAND() * 9), '7', '0') INTO v_loan_amount;
END;
BEGIN
SELECT RPAD(FLOOR(1 + RAND() * 9), '5', '0') INTO v_month_pay; #์์ ๊ฐ์์ผํ๋ ๋
END;
SET v_total_pay = 0;
SET v_interest = v_loan_amount * 0.011; #์ด์๋ 1.1% ๋ก ๋์ผ ์ ์ฉ
SET v_balance = v_loan_amount - v_total_pay;
INSERT INTO TB_LOAN (LOAN_NO, EMP_NO, LOAN_DATE, LOAN_AMOUNT, TOTAL_PAY, REMARK, INTEREST_RATE, INTEREST, IS_REPAY, REPAY_PERIOD, BALANCE, MONTH_PAY)
VALUES (NEXTVAL(LOAN_NO_SEQ), (SELECT EMP_NO FROM TB_EMP_MST WHERE KOR_NM = v_kor_nm), '20220501', v_loan_amount, v_total_pay, 'ํ์๊ธ ๋์ถ', '1.1', v_interest, 'N', '20220725', v_balance, v_month_pay);
SET i = i+1;
SET v_result = 0;
END;
END WHILE;
/** ํธ๋์ญ์
์ข
๋ฃ (์ปค๋ฐ) */
COMMIT;
END;
CALL INSERT_LOAN(@v_result);
์ฐธ๊ณ ํ ์ด๋ธ ์์ฑ๋ฌธ
CREATE DATABASE OSS;
USE OSS;
DROP TABLE TB_EMP_MST;
CREATE TABLE IF NOT EXISTS TB_EMP_MST (
EMP_NO INT(10) NOT NULL PRIMARY KEY AUTO_INCREMENT
, KOR_NM NVARCHAR(30) NOT NULL
, ENG_NM NVARCHAR(50)
, MPHONE NVARCHAR(30)
, ADDR NVARCHAR(150)
, DIVISION NVARCHAR(150) NOT NULL
, POSITION NVARCHAR(100) NOT NULL
, JOB NVARCHAR(50) NOT NULL
, DUTY NVARCHAR(50) NOT NULL
, EDUCATION NVARCHAR(100)
, WORK_TYPE NVARCHAR(10) NOT NULL
, EMP_STATUS NVARCHAR(10) NOT NULL
, JOIN_TYPE NVARCHAR(10) NOT NULL
, JOIN_DATE DATE NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
ALTER TABLE TB_EMP_MST ADD BIRTH_DATE DATE;
CREATE SEQUENCE EMP_NO_SEQ
INCREMENT BY 1
START WITH 10000
MAXVALUE 999999
CYCLE;
DROP TABLE TB_LOAN;
CREATE TABLE IF NOT EXISTS TB_LOAN (
LOAN_NO INT(10) NOT NULL AUTO_INCREMENT
, EMP_NO INT(10) NOT NULL
, LOAN_DATE DATE NOT NULL
, LOAN_AMOUNT NVARCHAR(30) NOT NULL
, TOTAL_PAY NUMERIC(10) NOT NULL
, REMARK NVARCHAR(50)
, INTEREST NUMERIC(10)
, INTEREST_RATE NUMERIC(10)
, IS_REPAY NVARCHAR(5) NOT NULL
, REPAY_PERIOD DATE
, BALANCE NUMERIC(10) NOT NULL
, PRIMARY KEY (LOAN_NO, EMP_NO)
, FOREIGN KEY (EMP_NO) REFERENCES TB_EMP_MST (EMP_NO)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
ALTER TABLE TB_LOAN MODIFY INTEREST_RATE DECIMAL(5, 2);
CREATE SEQUENCE LOAN_NO_SEQ
INCREMENT BY 1
START WITH 1
MAXVALUE 999999
CYCLE;
DROP TABLE TB_LOAN_HIST;
CREATE TABLE IF NOT EXISTS TB_LOAN_HIST (
EMP_NO INT(10) NOT NULL
, REPAY_DATE DATE NOT NULL
, LOAN_DATE DATE NOT NULL
, MONTH_PAY NUMERIC(10) NOT NULL
, MONTH_INTERREST NUMERIC(10) NOT NULL
, IS_REPAY NVARCHAR(5) NOT NULL
, PRIMARY KEY(EMP_NO, REPAY_DATE, LOAN_DATE)
, FOREIGN KEY (EMP_NO) REFERENCES TB_EMP_MST (EMP_NO)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
ALTER TABLE TB_LOAN_HIST MODIFY LOAN_DATE DATE AFTER EMP_NO;
2. ์ฌ๋ด๋์ถ์์ฅ๊ณผ 1:N mapping๋๋ ์๋ณ ๋์ถ์ํ๋ด์ญ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค๊ธฐ ์ํ ํ๋ก์์ ๋ฅผ ์์ฑํด๋ณด์
๋งค๋ฌ ํ๋ก์์ ธ๋ฅผ ๋๋ ค, ์๋ณ ๋์ถ์ํ ๋ด์ญ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๊ณ
์๋ณ ๋์ถ ์ํ ๋ด์ญ๊ณผ ์ฐ๊ณ๋ ์ฌ๋ด๋์ถ์์ฅ ๋ฐ์ดํฐ๋ฅผ ๊ฐฑ์ ํ๋ค.
USE OSS;
DELIMITER $$
CREATE OR REPLACE PROCEDURE INSERT_LOAN_HIST(IN v_repay_date DATE, OUT v_result INT)
/*
@DESCRIPTION
๋์ถ ์์ฅ(TB_LOAN)์ ๋ํ ์ ๋ณ ์ํ ๋ฐ์ดํฐ(TB_LOAN_HIST)๋ฅผ ์ํ ์๋ฅผ ๋งค๊ฐ๋ณ์๋ก ํ์ฌ ์๋ ์์ฑํ๊ณ
๋์ถ ์์ฅ(TA_LOAN) ๋ฐ์ดํฐ์ ๋์ถ ์ํ์ฌ๋ถ๊ฐ Y๊ฐ ๋ ๋ ๊น์ง, ์ต์ ์ํ์ก๊ณผ ์์ก ๋ฑ์ ๊ฐฑ์ ํ๋ค.
@RETURN
RESULT : ์คํจ(-1) ์ฑ๊ณต(0)
*/
BEGIN
DECLARE v_loan_cnt INT; #๋์ถ์์ฅ ๋ง์คํฐ length
DECLARE v_month_pay INT; #์ ์ํ์ก
DECLARE v_min_loan_no INT; #๋์ถ์์ฅ ๋ฒํธ(min)
DECLARE v_balance INT; #๋์ถ ์์ก
DECLARE v_total_pay INT; #์ด ์ํ์ก
DECLARE v_loan_amount INT; #๋์ถ ๊ธ์ก
DECLARE v_is_repay NVARCHAR(3); #์ต์ข
์ํ์ฌ๋ถ
DECLARE v_is_loan_hist INT; #์ ์ํ๋ด์ญ ์กด์ฌ์ฌ๋ถ
DECLARE i INT DEFAULT 0; #Loop ๋ณ์ i
/** ํธ๋์ญ์
์์ */
START TRANSACTION;
#๋์ถ์์ฅ ๋ง์คํฐ length ๋งํผ, loop
SELECT COUNT(*) INTO v_loan_cnt FROM TB_LOAN;
SELECT MIN(LOAN_NO) INTO v_min_loan_no FROM TB_LOAN;
WHILE i < v_loan_cnt DO
BEGIN
#์ํ ์ฌ๋ถ
BEGIN
SELECT IS_REPAY INTO v_is_repay FROM TB_LOAN WHERE LOAN_NO = v_min_loan_no + i;
END;
#์ ์ํ ๊ธ์ก
BEGIN
SELECT MONTH_PAY INTO v_month_pay FROM TB_LOAN WHERE LOAN_NO = v_min_loan_no + i;
END;
#๋์ถ ์์ก
BEGIN
SELECT BALANCE INTO v_balance FROM TB_LOAN WHERE LOAN_NO = v_min_loan_no + i;
END;
BEGIN
SELECT COUNT(1) INTO v_is_loan_hist FROM TB_LOAN_HIST WHERE REPAY_DATE = v_repay_date AND LOAN_NO = v_min_loan_no + i;
END;
#๋์ถ์์ฅ ๋ง์คํฐ์ ์ํ์ฌ๋ถ๊ฐ N์ด๊ณ , ๊ทธ ๋ฌ์ ์ด๋ฏธ ๋๋ฆฌ์ง ์์์ ๋์๋ง
IF v_is_repay = 'N' && v_is_loan_hist = 0
THEN
#๋จ, ์์ก์ด ์ ์ํ์ก๋ณด๋ค ๋ฏธ๋ง์ธ ๊ฒฝ์ฐ, ์ ์ํ์ก์ ์์ก์ด ๋๋ค.
IF v_month_pay > v_balance
THEN SET v_month_pay = v_balance;
END IF;
BEGIN
INSERT INTO TB_LOAN_HIST (EMP_NO, LOAN_NO, REPAY_DATE, LOAN_DATE, MONTH_PAY, MONTH_INTERREST, IS_REPAY)
VALUES ((SELECT EMP_NO FROM TB_LOAN WHERE LOAN_NO = v_min_loan_no + i), (SELECT LOAN_NO FROM TB_LOAN WHERE LOAN_NO = v_min_loan_no + i), v_repay_date, (SELECT LOAN_DATE FROM TB_LOAN WHERE LOAN_NO = v_min_loan_no + i), v_month_pay, (SELECT INTEREST FROM TB_LOAN WHERE LOAN_NO = v_min_loan_no + i), 'Y');
END;
BEGIN
#์์ํ๋ด์ญ ์์ฑ ํ, ๋์ถ์์ฅ์ ๊ฐฑ์
#1. ํด๋น ์ ๋ณ ์ํ๊ธ์ก์ ์ด ์ํ๊ธ์ก์ ๋ ํจ
#2. (์ด ๋์ถ๊ธ์ก - ์ด ์ํ๊ธ์ก) ๊ณ์ฐํ์ฌ ์์ก์ ๊ฐฑ์
#3. ์์ก์ด 0์ด๋ฉด ์ํ์ฌ๋ถ Y์ฒ๋ฆฌ
START TRANSACTION;
BEGIN
UPDATE TB_LOAN
SET TOTAL_PAY = TOTAL_PAY + v_month_pay
WHERE LOAN_NO = v_min_loan_no + i;
END;
COMMIT;
BEGIN
SELECT TOTAL_PAY INTO v_total_pay FROM TB_LOAN WHERE LOAN_NO = v_min_loan_no + i;
END;
BEGIN
SELECT LOAN_AMOUNT INTO v_loan_amount FROM TB_LOAN WHERE LOAN_NO = v_min_loan_no + i;
END;
BEGIN
IF v_loan_amount - v_total_pay = 0
THEN SET v_is_repay = 'Y';
ELSE
SET v_is_repay = 'N';
END IF;
END;
BEGIN
UPDATE TB_LOAN
SET BALANCE = v_loan_amount - v_total_pay
, IS_REPAY = v_is_repay
WHERE LOAN_NO = v_min_loan_no + i;
END;
END;
END IF;
END;
SET i = i + 1;
SET v_result = 0;
END WHILE;
/** ํธ๋์ญ์
์ข
๋ฃ (์ปค๋ฐ) */
COMMIT;
END;
CALL INSERT_LOAN(@v_result);
CALL INSERT_LOAN_HIST('20220725', @v_result);
CALL INSERT_LOAN_HIST('20220825', @v_result);
CALL INSERT_LOAN_HIST('20220925', @v_result);
CALL INSERT_LOAN_HIST('20221025', @v_result);
CALL INSERT_LOAN_HIST('20221125', @v_result);
CALL INSERT_LOAN_HIST('20221225', @v_result);
DELETE FROM TB_LOAN;
SELECT * FROM TB_LOAN;
DELETE FROM TB_LOAN_HIST;
SELECT * FROM TB_LOAN_HIST;
3. ๋ถ์์ ์ง๊ธ์ ๋ฌด์์๋ก ์ง์ ํ์ฌ ์ฌ์ ๋ง์คํฐ 100๊ฐ๋ฅผ ์์ฑํด์ฃผ๋ ํ๋ก์์ ๋ฅผ ๋ง๋ค์ด๋ณด์
USE OSS;
DELIMITER $$
CREATE OR REPLACE PROCEDURE INSERT_EMP(OUT v_result INT)
/*
@DESCRIPTION
์ง๊ธ, ์์์ ๋๋ค์ผ๋ก ํ๋ ์ธ์ฌ๋ง์คํฐ 100๊ฐ INERT
@RETURN
RESULT : ์คํจ(-1) ์ฑ๊ณต(0)
*/
BEGIN
DECLARE v_division INT; #๋ถ์
DECLARE v_kor_nm NVARCHAR(10); #์ฌ์๋ช
DECLARE v_position INT; #์ง๊ธ
DECLARE i INT DEFAULT 0; #Loop i ๋ณ์
DECLARE EXIT HANDLER FOR SQLEXCEPTION #SQL ERROR์ ROLLBACKํ๊ณ v_result -1 ์ฒ๋ฆฌ
BEGIN
ROLLBACK;
SET v_result = -1;
END;
/** ํธ๋์ญ์
์์ */
START TRANSACTION;
/** Loop */
WHILE i <= 100 DO
BEGIN
BEGIN
SELECT RPAD(FLOOR(1 + RAND() * 4), '3', '0') INTO v_division;
END;
BEGIN
SELECT RPAD(FLOOR(1 + RAND() * 5), '2', '0') INTO v_position;
END;
BEGIN
SELECT GET_KORNM() INTO v_kor_nm;
END;
BEGIN
INSERT INTO TB_EMP_MST (EMP_NO, KOR_NM, ENG_NM, MPHONE, ADDR, DIVISION, POSITION, JOB, DUTY, EDUCATION, WORK_TYPE, EMP_STATUS, JOIN_TYPE, JOIN_DATE, BIRTH_DATE)
VALUES (NEXTVAL(EMP_NO_SEQ), v_kor_nm, '', '', '', v_division, v_position, 'ํ์', '์น๊ฐ๋ฐ', '๋์กธ', '์ ๊ท์ง', '์ฌ์ง', '๊ฒฝ๋ ฅ', '2022-04-25', CURDATE());
SET i = i+1;
END;
SET v_result = 0;
END;
END WHILE;
/** ํธ๋์ญ์
์ข
๋ฃ (์ปค๋ฐ) */
COMMIT;
END;
CALL INSERT_EMP(@v_result);
SELECT @v_result;
3. ๋ฌด์์ ํ๊ธ ์ด๋ฆ์ return ํด์ฃผ๋ function ์์ฑ
- return ๊ฐ์ SET์ผ๋ก ์ด๊ธฐํ (SET v_real_nm = "";) ํด์ฃผ์ง ์์ผ๋๊น, ์ค๋ฅ๊ฐ ๋ฌ๋ค.
DELIMITER $$
CREATE OR REPLACE FUNCTION GET_KORNM() RETURNS NVARCHAR(20)
BEGIN
DECLARE v_first_nm NVARCHAR(10);
DECLARE v_middle_nm NVARCHAR(10);
DECLARE v_last_nm NVARCHAR(10);
DECLARE v_real_nm NVARCHAR(10);
SET v_real_nm = "";
BEGIN
SELECT SUBSTRING('๊น์ด๋ฐ์ต์ ๊ฐ์กฐ์ค์ฅ์์คํ์ ์๊ถํฉ์์ก์ ํ์ ๊ณ ๋ฌธ์์๋ฐฐ์กฐ๋ฐฑํ๋จ', rand() * 36 + 1, 1) INTO v_first_nm FROM dual;
END;
BEGIN
SELECT SUBSTRING('๋ฏผํ๋์ธ์งํ์ฌ์ฐ๊ฑด์ค์น์์ฑ์ง์ค์ ์๊ด์ํธ์คํํ์ฐ์์ฐ์ฒ ์์ค์', rand() * 36 + 1, 1) INTO v_middle_nm FROM dual;
END;
BEGIN
SELECT SUBSTRING('์ ์๋์ฑ์๋จ์์ผ์ฒ ๋ณํ์๋ฏธํ์์์ํฌ์์ง์๋น์ ์งํ์ฐ์ฑ๊ณต์์', rand() * 36 + 1, 1) INTO v_last_nm FROM dual;
END;
BEGIN
SELECT CONCAT(v_first_nm, v_middle_nm, v_last_nm) INTO v_real_nm;
END;
RETURN v_real_nm;
END;
4. ๋์ถ ์ํ ๋ด์ญ์ ์์ฑํ ํ, ๋์ถ ์ํ ๋ง์คํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐฑ์ ํ๋ ํ๋ก์์ ๋ฅผ ๋จ์ ์ฟผ๋ฆฌ๋ฌธ์ผ๋ก ๋ณ๊ฒฝํด๋ณด์ !
USE OSS;
#4์ ๋ฐ์ดํฐ ์ญ์
DELETE FROM TB_LOAN_HIST
WHERE REPAY_DATE = '2023-04-25';
#4์ HIST ๋ฐ์ดํฐ ์์ฑ
INSERT INTO TB_LOAN_HIST (EMP_NO, LOAN_NO, LOAN_DATE, REPAY_DATE, MONTH_PAY, MONTH_INTERREST, IS_REPAY)
SELECT
A.EMP_NO AS EMP_NO
, B.LOAN_NO AS LOAN_NO
, B.LOAN_DATE AS LOAN_DATE
, '2023-04-25' AS REPAY_DATE
, B.MONTH_PAY AS MONTH_PAY
, B.INTEREST AS MONTH_INTERREST
, 'Y' AS IS_REPAY
FROM TB_EMP_MST A
INNER JOIN TB_LOAN B
ON A.EMP_NO = B.EMP_NO;
#4์ HIST ๋ฐ์ดํฐ๋ฅผ ๊ธ์ด์์ ๋ง์คํฐ ๋ฐ์ดํฐ ์ต์ ๋ฒ์ ์ผ๋ก ๊ฐฑ์
UPDATE TB_LOAN AA
, (SELECT
A.LOAN_NO AS LOAN_NO
, CASE
WHEN A.BALANCE = '0' THEN A.BALANCE
WHEN A.BALANCE < (A.LOAN_AMOUNT - B.MONTH_PAY) THEN 0
ELSE A.LOAN_AMOUNT - B.MONTH_PAY
END AS AFTER_BALANCE #์
๋ฐ์ดํธ ํ ์์ก
, B.MONTH_PAY AS AFTER_TOTAL_PAY #์
๋ฐ์ดํธ ํ ์ด์ ๊น์ง ๊ฐ์ ๋
FROM TB_LOAN A
INNER JOIN (SELECT LOAN_NO AS LOAN_NO
, SUM(MONTH_PAY) AS MONTH_PAY
FROM TB_LOAN_HIST
GROUP BY LOAN_NO) B
ON A.LOAN_NO = B.LOAN_NO) BB
SET AA.BALANCE = BB.AFTER_BALANCE
, AA.TOTAL_PAY = BB.AFTER_TOTAL_PAY
, AA.IS_REPAY = (CASE WHEN BB.AFTER_BALANCE = 0 THEN 'Y' ELSE 'N' END) #IS_REPAY๋ ์์ก์ผ๋ก ๊ฒฐ์
WHERE AA.LOAN_NO = BB.LOAN_NO;
#๊ฒฐ๊ณผ
SELECT * FROM TB_LOAN;