SQL

===== ***** 반복문 ***** =====

에어팟맥스 2022. 7. 13. 17:27

        반복문에는 종류가 3가지가 있다.
        
        1. 기본 LOOP 문
        2. FOR LOOP 문
        3. WHILE LOOP 문



   ------ ===== ***** 1. 기본 LOOP 문 ***** ===== ------

      [문법]
      LOOP
          실행문장;
          EXIT WHEN 탈출조건;   -- 탈출조건이 참 이라면 LOOP 를 탈출한다.
      END LOOP;

 


 

[새로운 tbl_looptest_1 테이블 생성하기]

   create table tbl_looptest_1
   ( bunho      number
   , name       varchar2(50)
   );
   -- Table TBL_LOOPTEST_1이(가) 생성되었습니다.

 

   --- *** tbl_looptest_1 테이블에 행을 20000 개를 insert 해보기 *** ---

   create or replace procedure pcd_tbl_looptest_1_insert
   ( p_name   IN   tbl_looptest_1.name%type 
   , p_count  IN   number)  -- p_count 에 20000 을 넣을 것이다.
   is
        v_bunho   tbl_looptest_1.bunho%type := 0;  -- 변수의 초기화!!!
   begin
        LOOP
            v_bunho := v_bunho + 1;
            EXIT WHEN v_bunho > p_count;   -- 탈출조건이 참 이라면 LOOP 를 탈출한다.
            insert into tbl_looptest_1(bunho, name) values(v_bunho, p_name||v_bunho); -- 못빠져나가면 출력
        END LOOP;
   
   end pcd_tbl_looptest_1_insert;
   -- Procedure PCD_TBL_LOOPTEST_1_INSERT이(가) 컴파일되었습니다.

[ 실행 ]

   exec pcd_tbl_looptest_1_insert('홍길동', 20000);
   -- PL/SQL 프로시저가 성공적으로 완료되었습니다.
   
   
   select count(*)
   from tbl_looptest_1
   order by bunho asc; -- 20000
   
   
   rollback;
   
   
   select count(*)
   from tbl_looptest_1
   order by bunho asc; -- 0
   exec pcd_tbl_looptest_1_insert('엄정화', 50000);
   -- PL/SQL 프로시저가 성공적으로 완료되었습니다.
   
   
   commit;
   
   
   select count(*)
   from tbl_looptest_1
   order by bunho asc; -- 50000

 


--- ***** 이름이 없는 익명 프로시저(Anonymous Procedure)로 tbl_looptest_1 테이블에 행을 20000개 insert 하기 ***** -----

 

   declare
        v_bunho    number := 50000;   -- 변수의 선언 및 초기화
        v_count    number := 0;       -- 변수의 선언 및 초기화
        v_name     varchar2(20) := '이혜리';
   begin
        LOOP
            v_bunho := v_bunho + 1;
            v_count := v_count + 1;
            EXIT WHEN v_count > 20000;   -- 탈출조건이 참 이라면 LOOP 를 탈출한다.
            insert into tbl_looptest_1(bunho, name) values(v_bunho, v_name||v_count); -- 못빠져나가면 출력
        END LOOP;
   
   end;
   -- PL/SQL 프로시저가 성공적으로 완료되었습니다.

[ 실행 ]

   commit;
   
   select *
   from tbl_looptest_1
   where name like '이혜리%'
   order by bunho asc;
   
   select count(*)
   from tbl_looptest_1
   order by bunho asc; -- 70000

 

 

 

 


 ------ ===== ***** 2. FOR LOOP 문 ***** ===== ------

 

        [문법]
        
        for 변수 in [reverse] 시작값..마지막값 loop
            실행문장;
        end loop;

 


   truncate table tbl_looptest_1;
   -- Table TBL_LOOPTEST_1이(가) 잘렸습니다.
   
   
   select *
   from tbl_looptest_1;

 

[ 2. FOR LOOP 문 을 이용한 프로시저 생성]

   create or replace procedure pcd_tbl_looptest_1_insert_2
   ( p_name   IN   tbl_looptest_1.name%type 
   , p_count  IN   number)  -- p_count 에 20000 을 넣을 것이다.
   is  -- 변수의 초기화!!!
   begin
        for i in 1..p_count loop   -- 변수 i에 맨처음에는 1(시작값) 이 들어가고 다음으로는 매번 1 씩 증가된 값이 p_count 까지 i 에 들어간다.
            insert into tbl_looptest_1(bunho, name) values(i, p_name||i);
        end loop;
   
   end pcd_tbl_looptest_1_insert_2;
  -- Procedure PCD_TBL_LOOPTEST_1_INSERT_2이(가) 컴파일되었습니다.

 

[실행]

   exec pcd_tbl_looptest_1_insert_2('김민수', 20000);
   
   commit;
   
   select *
   from tbl_looptest_1
   order by bunho;
   
   select count(*)
   from tbl_looptest_1;

 


[  [reverse] & declare 사용 ]

   truncate table tbl_looptest_1;
   -- Table TBL_LOOPTEST_1이(가) 잘렸습니다.

 

   declare
        v_name  varchar2(20) := '이순신';
   begin
        for i in reverse 1..100 loop   -- 변수 i에 맨처음에는 100(시작값) 이 들어가고 다음으로는 매번 1 씩 감소된 값이 p_count 까지 i 에 들어간다.
            insert into tbl_looptest_1(bunho, name) values(i, v_name||i);
        end loop;
   
   end;
   -- PL/SQL 프로시저가 성공적으로 완료되었습니다.

[ 실행 ]

   commit;
   
   select *
   from tbl_looptest_1;
   
   select count(*)
   from tbl_looptest_1; n

 

 


   ------ ===== ***** 3. WHILE LOOP 문 ***** ===== ------

        [문법]
        WHILE 조건 LOOP
              실행문장;  -- 조건이 참이라면 실행문장; 을 실행함. 조건이 거짓이 되면 반복문을 빠져나감.
        END LOOP;
        
        WHILE NOT 조건 LOOP
              실행문장;  -- 조건이 참이라면 반복문을 빠져나감.(자바의 ! 과 같은 역할)
        END LOOP;

 


   truncate table tbl_looptest_1;
   -- Table TBL_LOOPTEST_1이(가) 잘렸습니다.

 

[ 3. WHILE LOOP 문 을 이용한 프로시저 생성]

   declare 
       v_name varchar2(20) := '유관순';  -- 변수의 선언 및 초기화
       v_cnt  number(3)    := 1;
   begin   
       while v_cnt <= 100 loop
             insert into tbl_looptest_1(bunho, name) values(v_cnt, v_name||v_cnt);  -- 조건이 참이라면 실행문장; 을 실행함. 조건이 거짓이 되면 반복문을 빠져나감.
             v_cnt := v_cnt + 1;
       end loop;
   end;
   -- PL/SQL 프로시저가 성공적으로 완료되었습니다.

 

[ 실행 ]

   commit;
   
   select *
   from tbl_looptest_1;
   
   truncate table tbl_looptest_1;
   -- Table TBL_LOOPTEST_1이(가) 잘렸습니다.

 

 

[not 사용하기]

   declare 
       v_name varchar2(20) := '유관순';  -- 변수의 선언 및 초기화
       v_cnt  number(3)    := 1;
   begin   
       while not (v_cnt > 100) loop -- not(탈출조건) 탈출조건이 참이라면 전체가 거짓이  되므로 반복문을 빠져나간다. // 괄호()는 생략 가능 
             insert into tbl_looptest_1(bunho, name) values(v_cnt, v_name||v_cnt);  -- 조건이 참이라면 실행문장; 을 실행함. 조건이 거짓이 되면 반복문을 빠져나감.
             v_cnt := v_cnt + 1;
       end loop;
   end;
   -- PL/SQL 프로시저가 성공적으로 완료되었습니다.

[ 실행 ]

   commit;
   
   select *
   from tbl_looptest_1;

 

 

 

 



[반복문 응용문제] - 비밀번호 제한하기

 

 

[ 새로운 tbl_member_test1 테이블 생성]

    create table tbl_member_test1
   (userid      varchar2(20)
   ,passwd      varchar2(20) not null
   ,name        varchar2(30) not null
   ,constraint  PK_tbl_member_test1_userid  primary key(userid)
   );
   -- Table TBL_MEMBER_TEST1이(가) 생성되었습니다.

[테스트]

   insert into tbl_member_test1(userid, passwd, name) values('leess', 'abcd1234', '이순신');
   -- 1 행 이(가) 삽입되었습니다.
   
   rollback;

 

 

[계획]

   exec pcd_tbl_member_test1_insert('leess', 'ad12$!', '이순신');
   --> insert 가 안되고 오류메세지 -20001 '암호는 최소 8글자 이상이면서 대소문자, 숫자, 특수문자가 혼합되어야 한다.'
   
   exec pcd_tbl_member_test1_insert('leess', 'abcd1234', '이순신');
   --> insert 가 안되고 오류메세지 -20001 '암호는 최소 8글자 이상이면서 대소문자, 숫자, 특수문자가 혼합되어야 한다.'
   
   exec pcd_tbl_member_test1_insert('leess', 'qwer1234$', '이순신');
   --> insert 가 안되고 오류메세지 -20001 '암호는 최소 8글자 이상이면서 대소문자, 숫자, 특수문자가 혼합되어야 한다.'
   
   exec pcd_tbl_member_test1_insert('leess', 'Qwer1234$', '이순신');
   --> 입력성공!!

 

[ 비밀번호를 제한하는 프로시저 pcd_tbl_member_test1_insert 생성 ]

   create or replace procedure pcd_tbl_member_test1_insert
   (p_userid IN tbl_member_test1.userid%type    -- IN 은 생략 가능하다. (OUT 은 불가.) ==> 생략하면 IN 으로 본다.
  , p_passwd    tbl_member_test1.passwd%type
  , p_name      tbl_member_test1.name%type
    )
   is
        v_length        number(2);
        error_insert    EXCEPTION;
        v_ch            varchar2(1);
        v_flag_upper    number(1) := 0;  -- 대문자 표식
        v_flag_lower    number(1) := 0;  -- 소문자 표식
        v_flag_num      number(1) := 0;  --  숫자 표식
        v_flag_special  number(1) := 0;  -- 특수문자 표식
        
   begin
        v_length := length(p_passwd);
        if ( v_length  < 8 or v_length > 20 ) then 
             raise error_insert;  -- 사용자가 정의하는 예외절(EXCEPTION) 을 구동하라.
        else 
             for i in 1..v_length loop
                v_ch := substr(p_passwd, i, 1);
                
                if( v_ch between 'A' and 'Z' )    then v_flag_upper := 1;
                elsif( v_ch between 'a' and 'z' ) then v_flag_lower := 1;
                elsif( v_ch between '0' and '9' ) then v_flag_num := 1;
                else v_flag_special := 1;
                end if;
                
             end loop;
             
             if ( v_flag_upper * v_flag_lower * v_flag_num * v_flag_special = 1 ) 
                then insert into tbl_member_test1(userid, passwd, name) values(p_userid, p_passwd, p_name);
                     dbms_output.put_line('>> 입력성공 <<');
             else
                raise error_insert; -- 사용자가 정의하는 예외절(EXCEPTION) 을 구동하라.
             end if;
             
        end if;
        
        exception
             when error_insert then 
                  raise_application_error( -20001, '암호는 최소 8글자 이상이면서 대소문자, 숫자, 특수문자가 혼합되어야 합니다.');
        
   end pcd_tbl_member_test1_insert;
   -- Procedure PCD_TBL_MEMBER_TEST1_INSERT이(가) 컴파일되었습니다.

 

[ 실행 ]

   
   exec pcd_tbl_member_test1_insert('leess', 'ad12$!', '이순신');
   --> insert 가 안되고 오류메세지 -20001 '암호는 최소 8글자 이상이면서 대소문자, 숫자, 특수문자가 혼합되어야 한다.'
   
   exec pcd_tbl_member_test1_insert('leess', 'abcd1234', '이순신');
   --> insert 가 안되고 오류메세지 -20001 '암호는 최소 8글자 이상이면서 대소문자, 숫자, 특수문자가 혼합되어야 한다.'
   
   exec pcd_tbl_member_test1_insert('leess', 'qwer1234$', '이순신');
   --> insert 가 안되고 오류메세지 -20001 '암호는 최소 8글자 이상이면서 대소문자, 숫자, 특수문자가 혼합되어야 한다.'
   
   exec pcd_tbl_member_test1_insert('leess', 'Qwer1234$', '이순신');
   --> 입력성공!!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'SQL' 카테고리의 다른 글

배열처럼 사용되는 table 타입 변수  (0) 2022.07.14
사용자 정의 예외절(EXCEPTION)  (0) 2022.07.14
제어문(IF문)  (0) 2022.07.13
사용자 정의 함수(Function)  (0) 2022.07.12
PL/SQL(Procedure Language / Structured Query Language)  (0) 2022.07.12