반응형

[MariaDB] 마리아DB 스토어드 프로그램 - 트리거 Trigger (MySQL)

 

스토어드 프로그램 종류는 4가지 입니다.

  1. 스토어드 프로시저 Stored Procedure
  2. 스토어드 함수 Stored Function
  3. 커서 Cursor
  4. 트리거 Trigger

이번 포스팅에서는 4번째인 트리거(Trigger)에 대해 설명하겠습니다.

트리거는 (1) AFTER 트리거, (2) BEFORE 트리거가 있습니다.

 

AFTER 트리거는 테이블에 INSERT, UPDATE, DELETE 등의 작업이 일어났을 때 작동하는 트리거 입니다. 작업이 이러난 후에 작동합니다.

BEFORE 트리거는 이벤트가 발생하기 전에 작동합니다. AFTER와 마찬가지로 INSERT, UPDATE, DELETE 이벤트로 작동합니다.

 

AFTER 트리거를 활용해 회원정보의 변경 또는 삭제 시 데이터를 백업하기

먼저  insert, update 작업이리 얼아나는 경우, 변경되기 전에 데이터를 저장할 테이블을 생성합니다.

USE testDB;
CREATE TABLE backup_userTBL -- 유저테이블의 변경전 내용을 저장할 테이블 생성
(	userID char(8) NOT NULL PRIMARY KEY,	-- ID를 기본키로 설정
	name VARCHAR(10) NOT NULL,
    birthYear int NOT NULL,
    addr char(2) NOT NULL
    mobile1 char(3),
    mobile2 char(8),
    height smallint,
    mDate date,
    modType char(2),	--  변경된 타입 저장할 컬럼. '수정' 또는 '삭제' 저장
    modDate date,	-- 변경된 날짜 저장할 컬럼.
    modUser varchar(256)	-- 변경한 사용자 저장할 컬럼
);

 

변경과 삭제가 발생할 때 작동하는 트리거를 userTBL에 부착합니다.

변경이 발생했을 때 작동하는 backupUserTbl_UpdateTRG 트리거를 작성합니다.

DROP TRIGGER IF EXISTS backUserTbl_UpdateTrg;	-- 트리거가 존재하면 삭제
DELIMITER //	-- 스토어드 프로그램 시작
CREATE TRIGGER backUserTbl_UpdateTrg  -- 트리거 생성
    AFTER UPDATE -- 변경 후에 작동하도록 지정
    ON userTBL -- 트리거를 userTBL 테이블에 부착
    FOR EACH ROW 
BEGIN	-- 실행하게될 코드 시작
    INSERT INTO backup_userTBL VALUES( OLD.userID, OLD.name, OLD.birthYear, 
        OLD.addr, OLD.mobile1, OLD.mobile2, OLD.height, OLD.mDate, 
        '수정', CURDATE(), CURRENT_USER() );	-- OLD. 테이블은 update나 delete가 실행되기 전 잠깐 데이터가 저장되는 임시 테이블
END // 	-- 코드 끝
DELIMITER ;	--스토어드 프로글램 끝

 

삭제가 발생했을 때 작동하는 backupUserTbl_DeleteTrg 트리거를 작성합니다.

DROP TRIGGER IF EXISTS backUserTbl_DeleteTrg;
DELIMITER //
CREATE TRIGGER backUserTbl_DeleteTrg  -- 트리거 생성
    AFTER DELETE -- 삭제 후에 작동하도록 지정
    ON userTBL -- 트리거를 userTBL 테이블에 부착
    FOR EACH ROW 
BEGIN
    INSERT INTO backup_userTBL VALUES( OLD.userID, OLD.name, OLD.birthYear, 
        OLD.addr, OLD.mobile1, OLD.mobile2, OLD.height, OLD.mDate, 
        '삭제', CURDATE(), CURRENT_USER() );
END //
DELIMITER ;

 

다음은 usetTBL 테이블에서 UPDATE와 DELETE를 해봅니다.

UPDATE userTBL SET addr = '서울' WHERE userID = 'AAA';
DELETE FROM userTBL WHERE height >= 180;

 

마지막으로 userTBL과 backup_userTBL 테이블을 조회하여 변경 된 사항을 확인합니다.

SELECT * FROM userTBL;	-- update, delete가 잘 실행되어 있음을 확인
SELECT * FROM backup_userTBL;	-- update, delete 된 데이터를 보관하고 mod값들도 정상 작동 확인

 

트리거가 생성하는 임시테이블(NEW, OLD)

트리거에서는 INSERT, UPDATE, DELETE 작업 수행시 임시로 사용되는 시스템 테이블 NEW, OLD가 있습니다.

 

먼저, NEW 테이블은 INSERT, UPDATE 작업 시 변경할 새로운 데이터를 잠깐 저장해 둡니다.

그 후에 NEW 테이블의 값을 변경하고자 했던 테이블에  입력, 변경하는 것 입니다.

그래서 NEW 테이블의 값을 조작하면 변경하고자 했던 테이블의 최종 입력, 변경하는 값을 새로운 값으로 변경할 수 있습니다.

INSERT(새 값) -> NEW테이블(새 값 입력) -> 변경하고자한 테이블(새 값 입력)

 

 

다음으로 OLD 테이블은 DELETE, UPDATE 작업이 수행될때 삭제, 변경되기 전에 예전 값을 임시 저장하는 테이블입니다.

DELETE(예전 값) -> 변경하고자한 테이블(예전 값 삭제) -> OLD테이블(예전 값 존재)

 

UPDATE의 경우 위에 NEW와 OLD가 모두 발생하게 됩니다.

UPDATE(새 값, 예전 값) -> NEW테이블(새 값 입력) -> 변경하고자한 테이블(예전값 삭제, 새값 입력) -> OLD테이블(예전 값 존재)

 

트리거의 작동 시에 새로 입력/변경되는 새로운 데이터를 참조하기 위해서는 NEW 테이블을 참조하고, 변경되기 전의 예전 데이터를 참조하기 위해서는 OLD 테이블을 참조하면 됩니다.

 

 

BEFORE 트리거를 활용해 생년이 잘못 입력시 생년을 수정하여 입력하기

USE testDB;
DROP TRIGGER IF EXISTS userTBL_BeforeInsertTrg;
DELIMITER // 
CREATE TRIGGER userTBL_BeforeInsertTrg  -- 트리거 생성
    BEFORE INSERT -- INSERT 전에 사용되도록 
    ON userTBL -- 트리거를 userTBL 테이블에 부착
    FOR EACH ROW 
BEGIN
    IF NEW.birthYear < 1900 THEN	-- NEW테이블의 생년 값이 1900년 미만으로 입력 시
        SET NEW.birthYear = 0;	-- NEW테이블의 생년 값을 0으로 설정
    ELSEIF NEW.birthYear > YEAR(CURDATE()) THEN	-- 또는, NEW테이블의 생년 값이 올해보다 초과할 때는
        SET NEW.birthYear = YEAR(CURDATE());	-- NEW테이블의 생년 값을 올해년도로 설정
    END IF;
END // 
DELIMITER ;

 

INSERT 두개를 실행하여 생년을 잘못 입력시 BEFORE 트리거가 잘 작동하는지 확인합니다.

INSERT INTO userTBL VALUES('BBB', '비비비', 1777, '부산', '011', '2222222', 191, '2020-10-01');	-- 1900년 미만 생년 트리거 발생시킴
INSERT INTO userTBL VALUES('CCC', '시시시', 2999, '대구', '011', '3333333', 161, '2010-2-20');	-- 올해보다 높은 생년 트리거 발생시킴

 

userTBL 테이블을 확인하여 트리거가 정상작동 한 INSERT 값이 입력 되었는지 확인해 봅니다.

SELECT * FROM userTBL;

 

 

트리거 확인 및 트리거 삭제 방법

SHOW TRIGGERS FROM DB명;	-- DB에 있는 트리거 보여줌

DROP TRIGGER 트리거명;	-- '트리거명' 트리거를 삭제

 

 

중첩트리거 활용하기

활용 시나리오

  1. 구매 테이블, 물품 테이블, 배송 테이블 3개의 테이블이 존재합니다.
  2. 고객이 물건을 구매 시 구매테이블에 값이 INSERT 됩니다.
  3. 구매테이블에 값이 INSERT 될 경우 -> 트리거로 물품테이블의 물품 남은 갯수를 수정시킵니다.(UPDATE)
  4. 물품테이블의 값이 UPDATE 될경우 -> 트리거로 배송테이블에 배송할 물품명과 물품갯수를 입력합니다.(INSERT)

먼저 테이블들을 생성합니다.

DROP DATABASE IF EXISTS testDB;	-- 만약 testDB DB가 존재한다면 삭제
CREATE DATABASE IF NOT EXISTS testDB;	-- testDB 생성

USE testDB;	--testDB 사용
CREATE TABLE orderTbl -- 구매 테이블 생성
	(orderNo INT AUTO_INCREMENT PRIMARY KEY, -- 구매 일련번호, 자동증가, 기본키
	 userID VARCHAR(5), -- 구매한 회원아이디
	 prodName VARCHAR(5), -- 구매한 물건명
	 orderamount INT );  -- 구매한 개수
    
CREATE TABLE prodTbl -- 물품 테이블 생성
	( prodName VARCHAR(5), -- 물건 이름
	  account INT ); -- 남은 물건수량
     
CREATE TABLE deliverTbl -- 배송 테이블 생성
	( deliverNo  INT AUTO_INCREMENT PRIMARY KEY, -- 배송 일련번호, 자동증가, 기본키
	  prodName VARCHAR(5), -- 배송할 물건명		  
	  account INT UNIQUE); -- 배송할 물건개수

 

물품테이블에 몇 가지 값을 입력합니다.

INSERT INTO prodTbl VALUES('냉장고', 999);
INSERT INTO prodTbl VALUES('TV', 999);
INSERT INTO prodTbl VALUES('세탁기', 999);

 

중첩트리거를 생성합니다.

-- 물품 테이블에서 개수를 감소시키는 트리거
DROP TRIGGER IF EXISTS orderTrg;	-- 트리거가 존재한다면 삭제
DELIMITER // 	-- 스토어드 프로그램 시작
CREATE TRIGGER orderTrg  -- 트리거 orderTrg 생성
    AFTER  INSERT 	-- 입력 후에 실행되도록 설정
    ON orderTBL -- 트리거를 orderTBL 테이블에 부착
    FOR EACH ROW 
BEGIN
    UPDATE prodTbl SET account = account - NEW.orderamount 	-- prodTbl 테이블의 account 값을 NEW테이블의 orderamount 값으로 빼서 저장
        WHERE prodName = NEW.prodName ;	-- prodName명이 NEW테이블의 prodName명과 같은 제품을 찾아서
END // 
DELIMITER ;


-- 배송테이블에 새 배송 건을 입력하는 트리거
DROP TRIGGER IF EXISTS prodTrg;
DELIMITER // 
CREATE TRIGGER prodTrg  -- 트리거 prodTrg 생성
    AFTER  UPDATE 	-- 수정 후에  실행되도록 설정
    ON prodTBL -- 트리거를 prodTBL 테이블에 부착
    FOR EACH ROW 
BEGIN
    DECLARE orderAmount INT;	-- 변수 orderAmount INT형으로 선언
    SET orderAmount = OLD.account - NEW.account;	-- 주문 개수 = (변경 전의 개수 - 변경 후의 개수)
    INSERT INTO deliverTbl(prodName, account)	-- deliverTbl테이블에 입력
        VALUES(NEW.prodName, orderAmount);	-- 입력값: NEW테이블의 제품명, 변수 orderAmount 값(주문개수)
END // 
DELIMITER ;

 

물건을 구매했다고 가정하고 주문테이블에 값을 입력해봅니다.

INSERT INTO orderTbl VALUES (NULL,'AAA', '냉장고', 5);

 

중첩트리거가 잘 작동했는지 테이블들을 확인합니다.

SELECT * FROM orderTbl;	-- 주문 INSERT가 입력되었는지 확인
SELECT * FROM prodTbl;	-- oserTBL 테이블 INSERT 이후에 트리거가 작동했는지 확인.
SELECT * FROM deliverTbl;	-- prodTBL 테이블 UPDATE 이후에 트리거가 작동했는지 확인.

 

만약 중첩트리거가 작동 중 마지막 트리거가 실패 할 경우 앞선 트리거들도 모두 롤백이 됩니다.

 

 

[MariaDB] 전체보기

 

 

'MariaDB' 카테고리의 글 목록

전산 관련 경험을 기록 하는 곳

reddb.tistory.com

반응형
반응형

[MariaDB] 마리아DB 스토어드 프로그램 - 커서 Cursor (MySQL)

 

스토어드 프로그램 종류는 4가지 입니다.

  1. 스토어드 프로시저 Stored Procedure
  2. 스토어드 함수 Stored Function
  3. 커서 Cursor
  4. 트리거 Trigger

 

이번 포스팅에서는 3번째인 커서(Cursor)에 대해 설명하겠습니다.

커서는 스토어드프로시저 내부에서 사용됩니다. 커서는 프로그래밍 언어의 파일처리 방법처럼 파일을 열고, 한 행씩 데이터를 처리합니다.

 

커서의 처리순서는 일반적으로 아래의 순서와 같이 처리됩니다.

  1. 커서의 선언 : DECLARE CURSOR
  2. 반복 조건 선언 : DECLARE CONTINUE HANDLER (더이상 읽을 행이 없을 경우에, 실행할 내용 설정)
  3. 커서 열기 : OPEN
  4. 커서에서 데이터 가져오기 : FETCH ( LOOP~END, LOOP문으로 반복 구간 지정 시작)
  5. 데이터 처리 (LOOP문으로 반복구간 지정 끝)
  6. 커서 닫기 : CLOSE

커서를 활용하여 프로시저에서 고객 평균 키 계산 예제

DROP PROCEDURE IF EXISTS cursorProc;	-- cursorProc 프로시저가 존재한다면 삭제
DELIMITER $$	-- 스토어드 프로그램 시작
CREATE PROCEDURE cursorProc()	- cursorProc 프로시저 생성
BEGIN	-- 프로시저 코드 시작
    DECLARE userHeight INT; -- 변수 userHeight INT형 선언. 고객의 키
    DECLARE cnt INT DEFAULT 0; -- 변수 cnt INT형 기본값 0으로 선언. 고객의 인원 수(=읽은 행의 수)
    DECLARE totalHeight INT DEFAULT 0; -- 변수 totlaHeight INT형 기본값 0으로 선언. 키의 합계

    DECLARE endOfRow BOOLEAN DEFAULT FALSE; -- 변수 endOfRow 선언. 행의 끝 여부(기본을 FALSE)

    DECLARE userCuror CURSOR FOR	-- 아래줄 셀렉트를 userCuror 커서로 선언
        SELECT height FROM userTBL;	-- userTBL 테이블에서 키만 선택해서 윗줄 userCuror에

    DECLARE CONTINUE HANDLER -- 행의 끝이면, SET endOfRow = TRUE (변수에 TRUE를 대입) 
        FOR NOT FOUND SET endOfRow = TRUE;

    OPEN userCuror;  -- 커서 열기

    cursor_loop: LOOP	-- 루프할 명칭: LOOP 시작
        FETCH  userCuror INTO userHeight; -- 11번 줄에서 선언한 userCuror(키)값을 userHeight 변수에 입력. 고객 키 1개를 대입

        IF endOfRow THEN -- 더이상 읽을 행이 없으면 Loop를 종료
            LEAVE cursor_loop;	-- 루프를 떠남
        END IF;

        SET cnt = cnt + 1;	-- cnt를 1증가
        SET totalHeight = totalHeight + userHeight;        	= totalHeight 변수에 합산
    END LOOP cursor_loop;	-- 루프 끝나고 cursor_loop 시작점으로 다시 올라감
    
    -- 고객 키의 평균을 출력한다.
    SELECT CONCAT('고객 키의 평균 ==> ', (totalHeight/cnt));

    CLOSE userCuror;  -- 커서 닫기
END $$	-- 프로시저 코드 끝
DELIMITER ;	-- 스토어드 프로그램 끝

CALL cursorProc();	-- 프로시저 cursorProc를 호출

 

고객 테이블의 구매 총액에 따라 구매등급 추가 예제

USE sqlDB;	-- sqlDB 사용
ALTER TABLE userTBL ADD grade VARCHAR(5);  -- 고객 등급 열 grade 추가


DROP PROCEDURE IF EXISTS gradeProc;	-- gradeProc 프로시저가 존재하면 삭제
DELIMITER $$
CREATE PROCEDURE gradeProc()
BEGIN
    DECLARE id VARCHAR(10); -- 변수 id VARCHAR(10). 사용자 아이디를 저장할 변수
    DECLARE hap BIGINT; -- 변수 hap BIGINT. 총 구매액을 저장할 변수
    DECLARE userGrade CHAR(5); -- 변수 userGrade CHAR(5). 고객 등급 변수
    
    DECLARE endOfRow BOOLEAN DEFAULT FALSE; 	-- 변수 endOfRow 기본값 FALSE로 선언.

    DECLARE userCuror CURSOR FOR-- 아래 셀렉트로 조회된 userid, sum값을 userCuror 커서로 선언
        SELECT U.userid, sum(price*amount)	-- userTBL의 userid, sum값을 윗줄 userCuror로
            FROM buyTBL B
                RIGHT OUTER JOIN userTBL U
                ON B.userid = U.userid
            GROUP BY U.userid, U.name ;

    DECLARE CONTINUE HANDLER 	-- 행의 끝까지 가서 더이상 찾을수 없을때.(NOT FOUND)
        FOR NOT FOUND SET endOfRow = TRUE;	-- 변수 endOfRow 값을 TRUE로 대입

    OPEN userCuror;  -- 커서 열기
    grade_loop: LOOP	-- 루프명 : LOOP 시작
        FETCH  userCuror INTO id, hap; -- 15행에서 선언한 userid, sum의 첫 행 값을 id, hap에 대입
        IF endOfRow THEN	-- 행이 끝나는 경우 endOfRow값이 트루가 됨
            LEAVE grade_loop;	-- 루프명 루프를 떠남
        END IF;

        CASE  	-- 케이스문
            WHEN (hap >= 1500) THEN SET userGrade = '최우수고객';	-- userCuror의 sum값에서 대입받은 hap값에 금액에 따라 userGrade 변수에 값을 대입
            WHEN (hap  >= 1000) THEN SET userGrade ='우수고객';
            WHEN (hap >= 1) THEN SET userGrade ='일반고객';
            ELSE SET userGrade ='유령고객';
         END CASE;

        UPDATE userTBL SET grade = userGrade WHERE userID = id;	-- userTBL의 테이블에서 id로 검색해서 위에서 선언한 userGrade값을 grade에 대입
    END LOOP grade_loop;	-- 루프 끝. 루프명(grade_loop) 시작점으로 이동

    CLOSE userCuror;  -- 커서 닫기
END $$
DELIMITER ;

CALL gradeProc();	-- gradeProc 프로시저 호출
SELECT * FROM userTBL;	-- userTBL 테이블 셀렉트하면 사용자의 등급이 추가되어 있음

 

 

[MariaDB] 전체보기

 

 

'MariaDB' 카테고리의 글 목록

전산 관련 경험을 기록 하는 곳

reddb.tistory.com

반응형
반응형

[MariaDB] 마리아DB 스토어드 프로그램 - 스토어드 함수 Stored Function (MySQL)

 

스토어드 프로그램 종류는 4가지 입니다.

  1. 스토어드 프로시저 Stored Procedure
  2. 스토어드 함수 Stored Function
  3. 커서 Cursor
  4. 트리거 Trigger

 

이번 포스팅에서는 2번째인 스토어드 함수(Stored Function)에 대해 설명하겠습니다.

MariaDB에서는 다양한 내장함수를 제공합니다. 자세한 내용은 아래 포스팅에서 확인 가능합니다.

 

[MariaDB] 마리아DB SQL 쿼리 고급 - 내장 함수 (MySQL)

[MariaDB] 마리아DB SQL 쿼리 고급 - 내장 함수 (MySQL) 제어 흐름 함수 IF(수식, 참, 거짓) /* 수식이 참이면 2번째 값 출력, 수식이 거짓이면 3번째 값 출력 */ SELECT IF (100>200, '참이다', '거짓이다'); --..

reddb.tistory.com

그러나, MariaDB가 사용자가 원하는 모든 함수를 제공하지는 않습니다. 사용자마다 자기가 원하는 함수가 있을 수 있고 그런 함수는 직접 함수를 만들어서 사용 해야 합니다.

이렇게 사용자가 직접 만들어 쓰는 함수를 스토어드 함수(Stored Function)이라고 합니다.

 

스토어드 함수의 사용 예제

-- 스토어드 함수 예제
USE sqlDB;	-- sqlDB 사용 선언
DROP FUNCTION IF EXISTS userFunc;	-- suerFunc 함수가 존재하면 삭제
DELIMITER $$	-- 스토어드 프로그램 시작 선언
CREATE FUNCTION userFunc(value1 INT, value2 INT)	-- userFunc 함수를 생성. INT형 value1,2를 매개변수로 받음
    RETURNS INT	-- INT형을 반환 하기로 선언 (스토어드 함수는 RETURNS문으로 반환할 데이터 형식을 선언함)
BEGIN	-- 코드시작
    RETURN value1 + value2;	--RETURN문으로 하나의 값을 반환함. 매개변수(파라미터) value1,2를 더하여 반환
END $$	-- 코드 끝
DELIMITER ;	-- 스토어드 프로그램 끝

SELECT userFunc(100, 200);	-- 전달인자(아귀먼트) 100,200으로 userFunc 함수 호출

 

출생년도를 입력하면 나이가 출력되는 함수 예제

USE sqlDB;
DROP FUNCTION IF EXISTS getAgeFunc;
DELIMITER $$
CREATE FUNCTION getAgeFunc(bYear INT)	-- getAgreFunc 함수 생성. bYear 매개변수 INT형
    RETURNS INT	-- 리턴 데이터 형식 INT형
BEGIN
    DECLARE age INT;	-- 변수  age INT형 선언
    SET age = YEAR(CURDATE()) - bYear;	-- 변수 age에 지금년도에서 bYear 매개변수를 뺀 후 입력(나이계산)
    RETURN age;	-- age 값을 반환
END $$
DELIMITER ;

SELECT getAgeFunc(1979);	-- 1979값을 전달인자(아귀먼트)로 getAgeFunc 함수를 호출하여 나이를 계산

SELECT getAgeFunc(1979) INTO @age1979;	-- 1979값으로 함수를 호출하여 리턴받은 나이를 변수 @age1979에 입력(저장)
SELECT getAgeFunc(1997) INTO @age1997;	-- 1997값으로 함수를 호출하여 리턴받은 나이를 변수 @age1997에 입력(저장)
SELECT CONCAT('1997년과 1979년의 나이차 ==> ', (@age1979-@age1997));	-- 두변수의 차를 계산하여 CONCAT 출력

SELECT userID, name, getAgeFunc(birthYear) AS '만 나이' FROM userTBL;	-- 테이블 조회시 생년이 아닌 나이로 계산하여(함수이용) 출력

 

스토어드 함수 내용 확인

SHOW CREATE FUNCTION 함수명;

 

스토어드 함수 삭제

DROP FUNCTION 함수명;

 

 

[MariaDB] 전체보기

 

 

'MariaDB' 카테고리의 글 목록

전산 관련 경험을 기록 하는 곳

reddb.tistory.com

반응형
반응형

[MariaDB] 마리아DB 스토어드 프로그램 - 스토어드 프로시저 Stored Procedure (MySQL)

 

스토어드 프로그램 종류는 4가지 입니다.

  1. 스토어드 프로시저 Stored Procedure
  2. 스토어드 함수 Stored Function
  3. 커서 Cursor
  4. 트리거 Trigger

이번 포스팅에서는 스토어드 프로시저(Stored Procedure)에 대해 설명하겠습니다.

스토어드 프로시저는 쿼리문의 집합으로 어떤 동작을 일괄 처리하기 위한 용도로 사용됩니다.

자주사용하는 쿼리가 있다면 매번 쿼리를 다 치는게 아니라 스토어드 프로시저로 만들어 모듈화 시킨 후 필요할 때마다 호출하여 사용하면 편리합니다.

 

스토어드 프로시저(Stored Procedure)의 장점도 4가지 입니다.

  1. DB의 성능을 향상시킬 수 있다.
  2. 유지관리가 간편하다
  3. 모듈식 프로그래밍이 가능하다
  4. 보안을 강화할 수 있다.

보안을 강화하는 방법은 사용자 별로 테이블에 접근권한을 주지 않고 스토어드 프로시저에만 접근권한을 줌으로써 테이블의 모든 정보를 사용자에게 노출하지 않고 프로시저에서 선택한 정보만 사용자에게 보여줄 수 있습니다.

 

스토어드 프로시저의 정의 형식 및 사용 예제

-- 스토어드 프로시저 형식
DELIMITER $$	--스토어드 프로그램 시작. 구분문자 $$ 선언. $$가 아니라 다른 문자로도 사용가능
CREATE PROCEDURE 스토어드프로시저이름(IN 또는 OUT 파라미터)	-- 파라미터를 받을때는 IN, 내보낼때는 OUT
BEGIN	--프로시저를 호출할때 실행 될 코드 시작위치
	......	--이 부분에 SQL 프로그램 코딩
END $$	--코딩 끝을 선언하고 구분문자 $$ 닫기
DELIMITER;	--최종적으로 스토어드프로시저 DELIMITER로 닫기

CALL 스토어드프로시저이름();	-- 필요할때 스토어드 프로시저 호출()



-- 스토어드 프로시저 예제
USE sqlDB;	-- DB사용
DROP PROCEDURE IF EXISTS userProc;	-- userProc가 있다면 삭제
DELIMITER $$	-- 스토어드 프로그램 시작. 구분문자 $$
CREATE PROCEDURE userProc()	--프로시저 userProc 생성
BEGIN	-- 코드 시작
    SELECT * FROM userTBL; -- 스토어드 프로시저 내용
END $$	-- 코드 끝. 구분문자 $$ 닫기
DELIMITER ;	-- 스토어드 프로그램 끝(닫기)

CALL userProc();	-- userProc 호출

 

매개변수가 있는 프로시저 사용 예제

USE sqlDB;	-- sqlDB사용
DROP PROCEDURE IF EXISTS userProc1;	-- userProc1이 존재하면 삭제
DELIMITER $$	-- 스토어드 프로그램 시작
CREATE PROCEDURE userProc1(IN userName VARCHAR(10))	-- userProc1 프로시저 생성, IN 입력매개변수명 데이터형식
BEGIN	-- 코딩 시작
  SELECT * FROM userTBL WHERE name = userName; 	-- 매개변수(파라미터, parameter) userName을 이용하여 넘어온 코딩
END $$	-- 코딩 끝
DELIMITER ;	--스토어드 프로그램 끝

CALL userProc1('김이름');	-- 전달인자(아귀먼트, argument) '김이름'을 넣어서 userProc1 호출

 

매개변수가 2개인 프로시저 사용 예제

DROP PROCEDURE IF EXISTS userProc2;	-- userProc2가 존재하면 삭제
DELIMITER $$	-- 스토어드 프로그램 시작
CREATE PROCEDURE userProc2(	--userProc2 프로시저 생성
    IN userBirth INT, 	-- 입력 매개변수(파라미터), 매개변수명 userBirth, INT 데이터형식
    IN userHeight INT	-- 입력 매개변수(파라미터), 매개변수명 userHeight, INT 데이터형식
)
BEGIN	--코드 시작
  SELECT * FROM userTBL 
    WHERE birthYear > userBirth AND height > userHeight;	-- 매개변수보다 크고 나이많은 user 선택
END $$	-- 코드 끝
DELIMITER ;	-- 스토어드 프로그램 끝

CALL userProc2(1970, 178);	-- 1970, 178 전달인자로 userProc2호출. 

 

출력매개변수 사용 예제

DROP PROCEDURE IF EXISTS userProc3;	
DELIMITER $$
CREATE PROCEDURE userProc3(
    IN txtValue CHAR(10),	-- 입력매개변수 IN, 매개변수명 txtValuer, 데이터형식 CHAR(10)
    OUT outValue INT	-- 출력매개변수 OUT, 매개변수명 outValue, 데이터형식 INT
)
BEGIN	-- 코딩시작
  INSERT INTO testTBL VALUES(NULL,txtValue);	-- 입력매개변수 txtValue를 이용하여 INSERT 쿼리실행
  SELECT MAX(id) INTO outValue FROM testTBL; 	-- testTBL테이블의 id값중 가장 높은 값을 출력매개변수 outValue에 집어 넣음
END $$
DELIMITER ;

CREATE TABLE IF NOT EXISTS testTBL(	-- 테이블이 존재하면 삭제하고 생성
    id INT AUTO_INCREMENT PRIMARY KEY, 	-- id 값은 INT로 자동증가. id는 생성 시 마다 1,2,3,4,... 로 증가
    txt CHAR(10)	-- txt는 not null을 안했기에 null값이 입력가능
);	-- 테이블을 프로시저보다 뒤에 생성할 수는 있지만 프로시저호출은 반드시 테이블 생성 후에 해야 함

CALL userProc3 ('테스트값', @myValue);	-- 전달인자(아귀먼트) '테스트값'을 txtValue로 보내고, outValue에 INTO(입력)된 id값을 @myValue 변수로 받음

SELECT CONCAT('현재 입력된 ID 값 ==>', @myValue);	-- @myValue 변수를 이용. INSERT시 AUTO_INCREMENT로 생성된 id값이 들어 있음

 

IF ELSE문을 활용한 스토어드 포르시저 예제

DROP PROCEDURE IF EXISTS ifelseProc;
DELIMITER $$
CREATE PROCEDURE ifelseProc(	-- ifelseProc 프로시저 생성
    IN userName VARCHAR(10)	--입력 매개변수 userNmae을 VARCHAR(10)형식으로 받음
)
BEGIN
    DECLARE bYear INT; -- 변수 bYear 선언
    SELECT birthYear into bYear FROM userTBL	-- userTBL테이블의 birthYear값을 bYear변수에 입력
        WHERE name = userName;	-- userTBL테이블의 name이 매개변수 userName과 같을 때
    IF (bYear >= 2000) THEN	-- IF시작. 만약 변수 bYear가 2000보다 크다면
            SELECT '21세기에 태어났습니다.';	-- 참일 경우 실행
    ELSE
            SELECT '20세기에 태어났습니다.';	-- 거짓일 경우 실행
    END IF;	--IF 종료
END $$
DELIMITER ;

CALL ifelseProc ('박이름');	-- 박이름을 전달인자(아귀먼트)로 ifelseProc 호출

 

CASE문을 활용한 스토어드 프로시저 예제

DROP PROCEDURE IF EXISTS caseProc;	-- caseProc 프로시저가 존재하면 삭제
DELIMITER $$
CREATE PROCEDURE caseProc(	-- 프로시저 caseProc 생성
    IN userName VARCHAR(10)	-- 입력매개변수 userName VARCHAR(10)
)
BEGIN
    DECLARE bYear INT; 	-- 변수 bYear INT 형식으로 선언
    DECLARE tti  CHAR(3);-- 변수 tti(띠) CAHR(3) 형식으로 선언
    SELECT birthYear INTO bYear FROM userTBL
        WHERE name = userName;
    CASE 	-- CASE문 시작
        WHEN ( bYear%12 = 0) THEN    SET tti = '원숭이';	-- 변수 bYear를 12로 나눈 나머지가 0일때(when), tti 변수에 원숭이 입력(SET)
        WHEN ( bYear%12 = 1) THEN    SET tti = '닭';
        WHEN ( bYear%12 = 2) THEN    SET tti = '개';
        WHEN ( bYear%12 = 3) THEN    SET tti = '돼지';
        WHEN ( bYear%12 = 4) THEN    SET tti = '쥐';
        WHEN ( bYear%12 = 5) THEN    SET tti = '소';
        WHEN ( bYear%12 = 6) THEN    SET tti = '호랑이';
        WHEN ( bYear%12 = 7) THEN    SET tti = '토끼';
        WHEN ( bYear%12 = 8) THEN    SET tti = '용';
        WHEN ( bYear%12 = 9) THEN    SET tti = '뱀';
        WHEN ( bYear%12 = 10) THEN    SET tti = '말';
        ELSE SET tti = '양';	-- 위에 WHEN에 없는 경우는 tti 변수를 '양'으로 SET
    END CASE;	-- CASE문 끝
    SELECT CONCAT(userName, '의 띠 ==>', tti);	-- (매개변수)userNAME의 띠 ==> (변수)tti 출력
END $$
DELIMITER ;

CALL caseProc ('강이름');	-- 강이름을 아귀먼트로 caseProc 호출

 

WHILE문을 활용한 스토어드 프로시저 예제

DROP TABLE IF EXISTS guguTBL;	
CREATE TABLE guguTBL (txt VARCHAR(100)); -- 구구단 저장용 테이블 생성

DROP PROCEDURE IF EXISTS whileProc;	-- whileProc 프로시저가 존재하면 삭제
DELIMITER $$
CREATE PROCEDURE whileProc()
BEGIN
    DECLARE str VARCHAR(100); -- 변수 srt 선언. 각 단을 문자열로 저장하기위한 변수
    DECLARE i INT; -- 변수 i 선언. 구구단 앞자리
    DECLARE k INT; -- 변수 k 선언. 구구단 뒷자리
    SET i = 2; -- 앞자리 변수i를 2로 입력하여 2단부터 계산
    
    WHILE (i < 10) DO  -- WHILE문 시작. i가 10보다 작다면 실행. 바깥 반복문. 2단~9단까지.
        SET str = ''; -- 변수 str 초기화. 각 단의 결과를 저장할 문자열 초기화
        SET k = 1; -- 변수 k는 1로 입력. 구구단 뒷자리는 항상 1부터 9까지.
        WHILE (k < 10) DO	-- WHILE문 시작. k가 1~9까지 돌아감(10보댜 작을때까지)
            SET str = CONCAT(str, '  ', i, 'x', k, '=', i*k); -- 문자열 만들기. i'x'k'='i*k
            SET k = k + 1; -- 뒷자리 변수 k 1증가
        END WHILE;	-- WHILE 시작위치로 돌아감 (뒷자리 k WHILE)
        SET i = i + 1; -- 앞자리 변수 I 1증가
        INSERT INTO guguTBL VALUES(str); -- 각 단의 결과 변수 str을 값으로 테이블에 입력(INSERT).
    END WHILE;	-- WHILE 시작위치르 돌아감 (앞자리 i WHILE)
END $$
DELIMITER ;

CALL whileProc();	-- 호출
SELECT * FROM guguTBL;	-- guguTBL 테이블 셀렉트. str값으로 입력된 테이블 데이터 SELECT 됨.

 

DECLARE HANDLER를 이용한 오류처리 스토어드 프로시저 예제

DROP PROCEDURE IF EXISTS errorProc;
DELIMITER $$
CREATE PROCEDURE errorProc()	-- erroProc 프로시저 생성
BEGIN
    DECLARE i INT; -- 변수 i 선언. 1씩 증가하는 값
    DECLARE hap INT; -- 변수 hap 선언. 합계 (정수형). 오버플로 발생시킬 예정.
    DECLARE saveHap INT; -- 변수 saveHap 선언. 합계 (정수형). 오버플로 직전의 값을 저장.

    DECLARE EXIT HANDLER FOR 1264 -- INT형 오버플로(에러 1264)가 발생하면 아래 BEGIN 수행
    BEGIN
        SELECT CONCAT('INT 오버플로 직전의 합계 --> ', saveHap);	--saveHap 출력
        SELECT CONCAT('1+2+3+4+...+',i ,'=오버플로');	--1씩 증가한값을 쌓았을때 최정적으로 더하게된 값이 i
    END;

    SET i = 1; -- i는 1부터 시작
    SET hap = 0; -- 합계를 누적

    WHILE (TRUE) DO  -- 무한 루프.
        SET saveHap = hap; -- 오버플로 직전의 합계를 저장
        SET hap = hap + i;  -- 오버플로가 나면 11, 12행을 수행함(DECLARE HANDLER)
        SET i = i + 1; 
    END WHILE;
END $$
DELIMITER ;

CALL errorProc();	-- errorProc 프로시저 호출

 

테이블 이름을 파라미터로 전달하는 방법 예제

DROP PROCEDURE IF EXISTS nameProc;
DELIMITER $$
CREATE PROCEDURE nameProc(
    IN tblName VARCHAR(20)	--입력매개변수(파리미터) tblName VARCHAR(20) 데이터형식
)
BEGIN	-- 코드시작
  SET @sqlQuery = CONCAT('SELECT * FROM ', tblName); 
  -- 변수 @sqlQuery에 CONCAT 내용 입력. CONCAT값은 매개변수 tblName을 이용한 SELCT문. FROM 뒤 공백 1개 주의.
  PREPARE myQuery FROM @sqlQuery;	-- 변수@sqlQuery를 'myQuery'에 준비시킴(PREPARE)
  EXECUTE myQuery;	-- 'myQuery' 실행
  DEALLOCATE PREPARE myQuery; 'myQuery' 준비를 해제시킴
END $$
DELIMITER ;

CALL nameProc ('userTBL');	-- userTBL값을 전달인자(아귀먼트)로 nameProc 프로시저 호출

 

 

[MariaDB] 전체보기

 

 

'MariaDB' 카테고리의 글 목록

전산 관련 경험을 기록 하는 곳

reddb.tistory.com

반응형
반응형

라즈베리파이4 비주얼스튜디오 코드(Visual Studio Code) 연동 개발환경 구축하기

 

먼저 비주얼시튜디오 코드가 이미 설치 되어있다는 전제하에 설명드리겠습니다.

설치가 안되신 분들은 아래 사이트에서 다운 받으시고 설치를 진행하시면됩니다.

(넥스트만 하면 설치가 완료됩니다)

code.visualstudio.com/

 

Visual Studio Code - Code Editing. Redefined

Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.  Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.

code.visualstudio.com

 

라즈베리파이 또한 SSH가 열려있다는 전제하에 설명드리겠습니다.

 

비주얼스튜디오 코드를 실행하시고 좌측 아이콘중 '확장' 아이콘을 클릭 후 'SSH'를 검색합니다. 

첫번째로 검색된 'Remote-SSH'를 선택하고 설치를 클릭합니다.

 

설치가 완료되면 좌측 하단에 녹색 버튼이 생깁니다. (원격 창 열기 버튼)

버튼을 누르면 중앙상단에 원격 접속을 위한 메뉴가 나옵니다. 여기서 'Remote-SSH: Connect to Host...'을 선택합니다.

 

다음은 '+ Add New SSH Host...'를 선택합니다.

 

다음은 '계정@주소'를 입력합니다. (저는 iptime의 ddns를 사용하여 접속하고 있습니다. 이전 포스팅 참조.)

 

다음은 위에서 입력했던 '계정@주소' SSH 구성파일을 저장할 폴더를 설정합니다. 저는 그냥 첫번째를 선택했습니다.

차후 해당 위치에 config파일을 여시면 주소를 수정, 추가, 삭제하기 편합니다.

 

이제 접속을 해봅니다.

좌측하단에 녹색버튼을 누르시고, 'Remote-SSH: Connect to Host...'을 선택합니다.

그리고 위에서 추가한 라즈베리파이 주소를 선택합니다.

 

이후 새로운 비주얼스튜디오 코드가 열리면서 운영체제를 묻습니다.

빠르게 linux를 선택하신 후, 비밀번호까지 입력하면 접속이 완료됩니다.

(일정시간동안 미입력시 자동으로 접속이 끊겨버립니다)

 

접속이 완료되면 좌측하단에 접속정보가 나타납니다.

 

메뉴에 있는 터미널의 새터미널을 클릭하면 라즈베리파이의 CLI 창이 뜹니다.

 

현재 위치를 찾는 pwd명령어와 현재폴더에 목록을 보는 ls를 입력해 보면 접속시 처음 위치가 pi계정의 home 폴더임을 알수 있습니다.

 

이제 메뉴의 파일 - 폴더열기로 /home/pi 폴더를 열어봅니다. (확인 클릭)

 

비밀번호를 한번 더 물어봅니다. 입력하시고 엔터를 누르면 됩니다.

 

/home/pi에 폴더와 파일 목록이 나옵니다. 파일을 선택하면 우측창에서 수정이 가능합니다.

 

라즈베리파이 전체보기

 

'라즈베리파이' 카테고리의 글 목록

전산 관련 경험을 기록 하는 곳

reddb.tistory.com

반응형