IT/Oracle

오라클 pl/sql 데이터타입, reference type(%type, %rowtype), composite type(record, table), 조건문(if, case), 반복문(for, while, loop)

노마드오브 2018. 7. 29. 00:07

-- as뒤의 select문에 해당하는 내용으로 pl_employees3라는 테이블 만들기

create table pl_employees3

as

select employee_id, first_name, salary

from employees;


-- pl_employees3 테이블 조회

select * from pl_employees3;


-- 조회된 컬럼 하나씩 변수에 담기

set serveroutput on -- 화면에 출력

declare

    vno pl_emloyees3.employee_id%type;    -- pl_emloyees3.employee_id의 데이터타입으로 vno 변수 생성

    vname pl_employees3.first_name%type;

    vsal pl_employees3.salary%type;

begin

    select employee_id, first_name, salary into vno, vname, vsal   -- employee_id, first_name, salary 각각의 데이터를 vno, vname, vsal에 담는다.

    from pl_employees3

    where employee_id = 180;

    dbms_output.put_line(vno);  -- vno 데이터값 출력

end;


-- reference type : rowtype에 조회된 레코드 한 행을 담기

set serveroutput on

declare

    v_row pl_employees3%rowtype;   -- begin에서 조회된 pl_employees3 레코드 전체를 v_row에 담는다.

begin

    select * into v_row

    from pl_employees3

    where employee_id=180;  

    dbms_output.put_line(v_row.employee_id||'==='||v_row.first_name||'==='||v_row.salary);  -- v_row출력

end;


-- join으로 조회된 컬럼을 변수에 담기

set serveroutput on

declare

    v_empid employees. employee_id%type;

    v_ename employees.first_name%type;

    v_deptno departments.department_id%type;

    v_dname departments.department_name%type;

begin

    select e.employee_id, e.first_name, d.department_id, d.department_name

    into v_empid, v_ename, v_deptno, v_dname

    from employees e, departments d

    where e. employee_id =180

    and e.department_id=d.department_id;

    dbms_output.put_line(v_empid||'==='||v_ename||'==='||v_deptno||'==='||v_dname);

end;    


-- 사용자 값을 입력받아 수식 적용 후 값 출력

set verify off  -- 입력값을 받기 전과 후의 plsql문을 출력해주는 명령어, off면 화면에 출력하지 않는다

set serveroutput on

declare

    v_no1 number := &no1;  -- number형 사용자 값을 입력받아 v_no1에 담기

    v_no2 number := &no2;

    v_sum number;  -- number형 변수 v_sum 선언

begin

    v_sum := v_no1 + v_no2;   -- v_no1 과 v_no2 의 합을 v_sum에 담기

    dbms_output.put_line('첫번째 수: '||v_no1||', 두번째 수: '||v_no2||' , 합은 : '||v_sum||' 입니다');  -- 각 변수 값 출력

end;


-- composite type : record 타입 정의, 선언, 사용

set serveroutput on;

declare

    type emp_record_type is record  -- emp_record_type라는 이름의 record타입 정의

    (emp_id employees.employee_id%type,

    f_name employees.first_name%type,

    e_sal employees.salary%type);

    v_rec1 emp_record_type;  -- 위에서 정의한 record타입 변수 선언

begin

    select employee_id, first_name, salary into v_rec1  -- record타입 변수에 조회된 데이터 담기

    from employees

    where employee_id = 180;

    dbms_output.put_line(v_rec1.emp_id||'=='||v_rec1.f_name||'=='||v_rec1.e_sal);   -- record안의 데이터 출력

end;    


-- composite type : table 타입 정의, 선언, 사용

set serverout on

declare

    t_name varchar2(20);  -- varchar2(20)형의 변수 선언

    type tbl_emp_name is table of -- tbl_emp_name이라는 이름의 table타입 정의

    employees.first_name%type  -- 테이블타입의 내용은 employees.first_name의 데이터형으로 구성

    index by binary_integer;  -- binary_integer형 인덱스

    v_name tbl_emp_name;  -- 테이블타입인 tbl_emp_name형으로 v_name 변수 선언

begin

    select first_name into t_name  -- 조회된 employees의 first_name을 t_name에 담는다

    from employees

    where employee_id = 180;

    v_name(0) := t_name;  -- t_name에 담긴 내용을 테이블타입인 v_name의0번째칸에 담는다

    dbms_output.put_line(v_name(0));  -- v_name의 0번째에 담긴 내용 출력

end;



-- 테이블 타입 정의, 선언, 사용, for 문에서 loop 돌리기

declare

    type e_table_type is table of  -- 테이블타입 정의

    employees.first_name%type  -- employees의 first_name 데이터형

    index by binary_integer;  -- binary_integer형 인덱스

    tab_type e_table_type;  -- e_table_type타입의 tab_type 변수 선언

    a binary_integer := 0;  -- binary_integer형 변수 a 선언

begin

    for i in (select first_name from employees) loop  -- select first_name from employees 값이 있는 동안 loop 실행, loop 시작

        a := a+1;

        tab_type(a) := i.first_name;  -- 테이블 타입 변수 tab_type의 a자리에 i의 first_name 담기

    end loop;  -- loop 끝

    for j in 1..a loop  -- 1부터 a까지 loop 실행

        dbms_output.put_line(tab_type(j));  -- 위에서 담았던 tab_type 내용 출력

    end loop;  -- loop 끝

end;


-- pl/sql문 밖에서 선언한 변수를 pl/sql문 안에서 사용하고, 밖에서도 사용하기

variable v_bind number;  -- pl/sql문 밖에서 변수 선언

begin 

    select (salary*12) into :v_bind  -- pl/sql문 밖에서 선언한 v_vind 변수에 salary*12 값 담기

    from employees

    where employee_id =180;

end;

/

print v_bind;  -- pl/sql문 밖에서 v_bind값 출력


-- pl/sql에서 if문 사용

declare

    vempid employees.employee_id%type;

    vfname employees.first_name%type;

    vdeptid employees.department_id%type;

    vdname varchar2(20);

begin

    select employee_id, first_name, department_id

    into vempid, vfname, vdeptid

    from employees

    where employee_id = 203;    

   

    if (vdeptid = 10) then  -- vdeptid값이 10이면,

        vdname := ' Administration';  -- vdname에 해당하는 내용 담기

    end if;  -- if문의 끝

    if (vdeptid = 20) then

        vdname := ' Marketing';

    end if;

    if (vdeptid = 30) then

        vdname := ' Perchasing';

    end if;

    if (vdeptid = 40) then

        vdname := ' Human Resources';

    end if;

    dbms_output.put_line(vempid||'=='||vfname||'=='||vdeptid||'=='||vdname);

end;


-- pl/sql에서 if-elsif 문 사용

declare

    vempid employees.employee_id%type;

    vfname employees.first_name%type;

    vdeptid employees.department_id%type;

    vdname varchar2(20);

begin

    select employee_id, first_name, department_id

    into vempid, vfname, vdeptid

    from employees

    where employee_id = 203;

    

    if (vdeptid = 10) then

        vdname := ' Administration';

    elsif (vdeptid = 20) then  -- elsif 스펠링 주의

        vdname := ' Marketing';

    elsif (vdeptid = 30) then

        vdname := ' Perchasing';

    elsif (vdeptid = 40) then

        vdname := 'Human Resources';

    end if;

    dbms_output.put_line(vempid||'=='||vfname||'=='||vdeptid||'=='||vdname);

end;


-- pl/sql에서 if-else 문 사용

set verify off

declare

    vempid employees. employee_id%type;

    vfname employees.first_name%type;

    vsal employees.salary%type;

    vcomm employees.commission_pct%type;

    vtotal number;

begin

    select employee_id, first_name, salary, commission_pct, salary*commission_pct

    into vempid, vfname, vsal, vcomm, vtotal

    from employees

    where employee_id = &empid; -- 사용자값 입력받기

    

    if vcomm > 0 then

        dbms_output.put_line(vfname||'사원의 보너스는 '||vtotal||'입니다.');

    else

        dbms_output.put_line(vfname||'사원의 보너스는 없습니다');

    end if;

end;

/


-- pl/sql에서 case 문 사용

set verify off

set serveroutput on

declare

    v_empid employees. employee_id%type;

    v_fname employees.first_name%type;

    v_deptid employees.department_id%type;

    v_dname varchar2(20);

begin

    select employee_id, first_name, department_id

    into v_empid, v_fname, v_deptid

    from employees

    where employee_id = &empid;

    v_dname := case v_deptid

                    when 10 then 'Administration'

                    when 20 then 'Marketing'

                    when 30 then 'Perchasing'

                    when 40 then 'Human Resources'

               end;  -- case문의 끝

    dbms_output.put_line(v_empid||'=='||v_fname||'=='||v_deptid||'=='||v_dname);

end;    

    

-- loop문

declare

    no1 number := 0;

begin 

    loop

    dbms_output.put_line(no1);

    no1 := no1 + 1;

    exit when no1 > 5;  -- no1이 5이상이면 loop 종료

    end loop;  -- loop문의 끝

end;

/


-- while문

declare

    no1 number := 0;

begin

    while no1 < 6 loop  -- -- no1이 6보다 작을때까지 loop 실행

        dbms_output.put_line(no1);

        no1 := no1 + 1;

    end loop;

end;

/


-- for문

begin

    for i in 0..5 loop  -- 0에서 5까지 반복

        dbms_output.put_line(i);

    end loop;

end;

/


-- for문 reverse 사용

declare

    i number;

begin

    for i in reverse 10..20 loop

        dbms_output.put_line(i);

    end loop;

end;