MySQL 테이블의 모든 행을 통한 루프
- MySQL 테이블의 모든 행을 통한 루프
-
저장 프로시저에서
WHILE루프를 사용하여 MySQL 테이블의 모든 행을 반복합니다. -
저장 프로시저에서
CURSOR를 사용하여 MySQL 테이블의 모든 행을 반복합니다. -
WHILE및CURSOR사용 비교
오늘 우리는 저장 프로시저에서 WHILE 및 CURSOR를 사용하여 MySQL 테이블의 모든 행을 반복하는 방법에 대해 배울 것입니다. 또한 각 기술의 장단점을 살펴보고 어떤 상황에 적합한지 구별할 것입니다.
MySQL 테이블의 모든 행을 통한 루프
특정 또는 여러 테이블에서 데이터를 읽고 삽입하기 위해 MySQL 테이블의 모든 행을 반복하는 데 사용할 수 있는 다양한 접근 방식에 대해 배웁니다. 코드 예제를 통해 각각 알아봅시다.
이를 위해 employees 테이블과 emp_performance 테이블이 있습니다. employees 테이블에는 속성(열 이름이라고도 함)으로 EMP_ID, FIRSTNAME, LASTNAME, GENDER 및 AGE가 있습니다.
emp_performance 테이블에는 PERFORM_ID, FIRSTNAME, LASTNAME 및 PERFORMANCE 필드가 있으며 여기서 FIRSTNAME 및 LASTNAME은 employees 테이블과 동일합니다.
매월 각 직원의 PERFORMANCE를 계산하기 위해 employees 테이블에서 FIRSTNAME 및 LASTNAME을 복사하여 emp_performance 테이블에 삽입해야 한다고 상상해 보십시오.
employees 테이블에서 필요한 값을 SELECT하고 emp_performance 테이블에 INSERT하고 나중에 PERFORMANCE 계산을 계속하는 방법이 있어야 합니다. 직원 및 emp_perfomance를 생성하여 우리와 함께 계속할 수도 있습니다. 코드는 아래에 나와 있습니다.
예제 코드:
#create an `employees` table
CREATE TABLE employees (
EMP_ID INT NOT NULL AUTO_INCREMENT,
FIRSTNAME VARCHAR(45) NOT NULL,
LASTNAME VARCHAR(45) NOT NULL,
GENDER VARCHAR(45) NOT NULL,
AGE INT NOT NULL,
PRIMARY KEY (EMP_ID));
#insert data
INSERT INTO employees (FIRSTNAME, LASTNAME, GENDER, AGE) VALUES
('Mehvish','Ashiq', 'Female', 30),
('Thomas', 'Christopher', 'Male', 22),
('John', 'Daniel', 'Male', 34),
('Saira', 'James', 'Female', 27);
#create a `emp_performance` table
CREATE TABLE emp_performance (
PERFORM_ID INT NOT NULL AUTO_INCREMENT,
FIRSTNAME VARCHAR(45) NOT NULL,
LASTNAME VARCHAR(45) NOT NULL,
PERFORMANCE VARCHAR(45) NULL,
PRIMARY KEY (PERFORM_ID));
저장 프로시저에서 WHILE 및 CURSOR를 사용하여 employees 테이블의 모든 행과 INSERT를 emp_performance 테이블로 반복할 수 있습니다.
저장 프로시저에서 WHILE 루프를 사용하여 MySQL 테이블의 모든 행을 반복합니다.
이제 테이블이 준비되었습니다. 따라서 employees 테이블에서 FIRSTNAME 및 LASTNAME을 SELECT하고 emp_performance 테이블에 INSERT에 다음 프로시저를 작성하고 실행할 수 있습니다.
예제 코드:
DROP PROCEDURE IF EXISTS CALCPERFORMANCE;
DELIMITER ;;
CREATE PROCEDURE CALCPERFORMANCE()
BEGIN
DECLARE length INT DEFAULT 0;
DECLARE counter INT DEFAULT 0;
SELECT COUNT(*) FROM employees INTO length;
SET counter=0;
WHILE counter<length DO
INSERT INTO emp_performance(FIRSTNAME, LASTNAME)
SELECT FIRSTNAME, LASTNAME FROM employees LIMIT counter,1;
SET counter = counter + 1;
END WHILE;
End;
;;
DELIMITER ;
CALL CALCPERFORMANCE();
레코드가 삽입되면 SELECT 명령을 사용하여 emp_performance 출력을 확인합니다.
SELECT * from emp_performance;
출력(WHILE 루프를 사용하는 emp_performance 테이블):
PERORM_ID |
FIRSTNAME |
LASTNAME |
PERFORMANCE |
|---|---|---|---|
| 1 | 메비쉬 | 아시크 | 없는 |
| 2 | 도마 | 크리스토퍼 | 없는 |
| 삼 | 남자 | 다니엘 | 없는 |
| 4 | 사이라 | 제임스 | 없는 |
CALCPERFORMANCE 저장 프로시저를 실행하면 PERFORM_ID, FIRSTNAME 및 LASTNAME만 채워집니다.
줄 번호를 사용한 코드 설명
- 라인 1은
CALCPERFORMANCE이름으로 이미 생성된 프로시저를 삭제합니다. - 라인 2는 기본 구분 기호를
;;로 변경합니다. 이런 식으로 SQL은 특정 작업을 수행하기 위한 프로시저를 작성하려고 할 때 모든 라인을 실행하지 않습니다. - 4행은 제공된 프로시저 이름을 사용하여 프로시저를 작성합니다.
- 이 절차에 필요한 모든 진술은 5행과 15행 사이에 작성됩니다.
- 라인 5는 절차를 시작합니다.
- 라인 6과 7은
DEFAULT값이 각각 0과 0인INT유형의길이와카운터라는 변수를 선언합니다. - 라인 8에서
employees테이블에서 개수를SELECT하고 해당 값을length변수에 할당합니다. - 라인 9는
카운터를 0으로 설정합니다. employees테이블에서FIRSTNAME및LASTNAME을SELECT하고emp_performance테이블로INSERT하는 10-14행의WHILE루프가 있습니다. 반복할 때마다 하나의 레코드만 선택되고 삽입된다는 점을 기억하십시오.- 라인 18은 구분 기호를 기본값
;으로 재설정합니다. - 19행은 프로시저를 호출합니다.
마찬가지로 CURSOR를 사용하여 MySQL의 모든 테이블 행을 반복할 수 있습니다. 다음 섹션을 봅시다.
저장 프로시저에서 CURSOR를 사용하여 MySQL 테이블의 모든 행을 반복합니다.
저장 프로시저에서 결과 집합을 처리하기 위해 CURSOR를 사용합니다. 이를 통해 쿼리에서 반환된 일련의 레코드(행)를 반복하고 모든 행을 개별적으로 처리할 수 있습니다.
그것을 사용하는 동안 CURSOR의 다음 속성이 있어야 합니다.
CURSOR는 민감합니다. 서버가 결과 테이블의 복사본도 만들 필요는 없습니다.CURSOR는 읽기 전용이므로 업데이트할 수 없습니다.CURSOR는 스크롤할 수 없습니다. 결과 집합의 레코드(행)를 건너뛰거나 건너뛰지 않고 한 방향으로만 탐색할 수 있습니다.
예제 코드:
DROP PROCEDURE IF EXISTS cursor_CALCPERFORMANCE;
DELIMITER ;;
CREATE PROCEDURE cursor_CALCPERFORMANCE()
BEGIN
DECLARE cursor_FIRSTNAME VARCHAR(45) DEFAULT "";
DECLARE cursor_LASTNAME VARCHAR(45) DEFAULT "";
DECLARE done INT DEFAULT FALSE;
DECLARE cursor_e CURSOR FOR SELECT FIRSTNAME,LASTNAME FROM employees;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cursor_e;
read_loop: LOOP
FETCH cursor_e INTO cursor_FIRSTNAME, cursor_LASTNAME;
IF done THEN
LEAVE read_loop;
END IF;
INSERT INTO emp_performance (FIRSTNAME,LASTNAME)
VALUES (cursor_FIRSTNAME, cursor_LASTNAME);
END LOOP;
CLOSE cursor_e;
END;
;;
DELIMITER ;
CALL cursor_CALCPERFORMANCE();
레코드가 삽입되면 SELECT 명령을 사용하여 emp_performance 출력을 확인합니다.
SELECT * from emp_performance;
출력(CURSOR를 사용하는 emp_performance 테이블):
PERORM_ID |
FIRSTNAME |
LASTNAME |
PERFORMANCE |
|---|---|---|---|
| 1 | 메비쉬 | 아시크 | 없는 |
| 2 | 도마 | 크리스토퍼 | 없는 |
| 삼 | 남자 | 다니엘 | 없는 |
| 4 | 사이라 | 제임스 | 없는 |
줄 번호를 사용한 코드 설명
- 1행은 같은 이름의 기존 프로시저를 삭제합니다.
- 라인 2는 구분 기호를
;;로 변경합니다. - 4행은 주어진 프로시저 이름을 사용하여 프로시저를 생성합니다.
- 필요한 모든 진술은 5행과 21행 사이에 작성됩니다.
- 라인 5는 절차를 시작합니다.
- 라인 6, 7 및 8은
VARCHAR(45),VARCHAR(45)및INT유형의cursor_FIRSTNAME,cursor_LASTNAME및done이라는 변수를 선언하며DEFAULT값은 다음과 같습니다. 각각"",""및FALSE입니다. - 라인 9는
SELECT문과 연관된CURSOR를 선언합니다. - 라인 10은
CURSOR가 결과 세트의 끝에 도달했음을 표시하기 위해finished변수가 사용되는NOT FOUND핸들러를 선언합니다. - 11행은
CURSOR를 엽니다. - 라인 12-19에서
FIRSTNAME및LASTNAME목록을 반복하여emp_performance테이블에INSERT합니다. - 라인 20은
CURSOR를 종료하고 라인 21은 저장 프로시저를 종료합니다. - 라인 24는 구분 기호를 기본값
;으로 재설정합니다. - 25행은 프로시저를 호출합니다.
WHILE 및 CURSOR 사용 비교
우리는 한 가지를 달성하는 데 여러 방법이 있을 때 각 접근 방식의 장단점을 알아야 합니다.
WHILE 루프의 장단점:
| 장점 | 단점 |
|---|---|
CURSOR보다 빠르고 최소 잠금을 사용합니다. |
앞뒤로 이동하기가 어렵습니다. |
그들은 tempdb에 데이터 사본을 만들지 않습니다. |
제대로 처리하지 않으면 무한 루프의 위험이 있습니다. |
CURSOR의 장단점:
| 장점 | 단점 |
|---|---|
| 저장 프로시저에 커서를 전달할 수 있습니다. | CTE 또는 WHILE 루프를 사용할 때보다 성능이 저하됩니다. |
커서는 조건이 필요하지 않으며 CURSOR에서 앞뒤로 이동할 수 있습니다. |
코드에 전역 커서가 있으면 오류가 발생할 위험이 있습니다. 어떻게? CURSOR는 코드에 중첩된 저장 프로시저에 의해 닫힐 수 있습니다. |
