Daily coding
Oracle day 7 - PL ( Procedural Language) : 기본문법 및 Script 구조, VArray, 본문
Oracle day 7 - PL ( Procedural Language) : 기본문법 및 Script 구조, VArray,
sunnnkim 2019. 12. 19. 18:16PL (1)
PL / SQL : Procedural Language / extension to Structured Query Language
Procedural = 처리자
- SQL을 확장한 순차적인 언어 -> Procedure, Function, Trigger
- SQL 문을 간단히 접근하기 위해서 작성해놓은 함수
+ script 추가해서 사용할 수 있음
- Script 구조
1. 선언부 : 사용할 변수/상수를 선언, 초기화 ( IS / DECLARE )
2. 실행부 : 실제 처리할 Query 부분이나 제어문 등을 활용. 실제 처리 ( BEGIN )
3. 예외처리부 : 각종 오류 부분 처리 (생략이 가능) ( EXCEPTION WHEN ~ THEN )
* SERVEROUTPUT ON / OFF
SET SERVEROUTPUT ON
-- 한번만 키면 쭉 켜져 있음
-- 반드시 PL 실행전에 켜주어야 정상 실행이 된다/
SET SERVEROUTPUT OFF
--> PL문 종료 후 서버아웃풋을 꺼준다.
* 실행부
BEGIN
dbms_output.put_line('HELLO PL');
-- 콘솔창에 메세지가 출력되는 코드
END; <-- 마지막에는 반드시 END; 로 닫아주어야 한다.
/ <---- / 도 붙여주기
-- 오리지널 코드에서는 END; 뒤에 반드시 / (슬래쉬) 입력해야함
* 선언부
DECLARE
-- 선언부
message VARCHAR2(10); -- 변수명 자료형;
BEGIN
-- 실행부
message := 'hello PL?'; -- 변수에 대입할 때는 : (콜론) 을 반드시 붙여준다
DBMS_OUTPUT.put_line('message=' || message); -- || 문자열끼리 더해주는 연산자
END;
/
< 여러가지 PL문법 >
1) if 문
DECLARE
counter INTEGER;
BEGIN
counter := 1;
counter := counter + 1;
IF counter = 0 THEN
DBMS_OUTPUT.put_line('RESULT : counter is null' );
ELSIF counter = 1 THEN
DBMS_OUTPUT.put_line('RESULT : counter is not null' );
END IF;
END;
/
2) FOR 문
DECLARE
counter INTEGER;
i INTEGER;
BEGIN
FOR i IN 1..9 LOOP ----> 1~9까지 루프
DBMS_OUTPUT.put_line('i=' || i );
counter:=i * 2;
DBMS_OUTPUT.put_line('2 * ' || '='|| counter );
END LOOP;
END;
/
3) loop 문
DECLARE
v_count NUMBER := 0; -- 선언과 동시에 초기화
v_total NUMBER := 0;
BEGIN
LOOP
EXIT WHEN v_count = 10; --> 루프문 탈출조건
v_count := v_count + 1;
v_total := v_total + v_count;
DBMS_OUTPUT.put_line('v_count = ' || v_count );
END LOOP;
DBMS_OUTPUT.put_line('v_total = ' || v_total );
END;
/
4) WHILE
DECLARE
v_count NUMBER := 0;
v_total NUMBER := 0;
BEGIN
WHILE v_count < 10 --> 탈출조건
LOOP ----> 이코드 아래에 루프문 작성
v_count := v_count + 1;
v_total := v_total + v_count;
END LOOP;
DBMS_OUTPUT.put_line('v_total = ' || v_total );
END;
/
5) GOTO
-- 자바 /c에서 없어짐
-- 이동(탈출)할 때 쓰임
DECLARE
v_name VARCHAR2(10) := 'LEE';
v_case NUMBER := 1;
BEGIN
CASE WHEN MOD (v_case, 2) = 0 THEN
GOTO test1; -- v_case를 2로 나눈 값이 0일때 test1로 가시오
WHEN MOD (v_case, 2) = 1 THEN
GOTO test2;
ELSE
GOTO ERR; -- 문자가 들어오면 에러로 표시하시오
END CASE;
-- 조건분기
<<test1>>
dbms_output.put_line(v_name || 'is woman'); -- 출력
GOTO sub_end;
<<test2>>
dbms_output.put_line(v_name || 'is man'); -- 출력
GOTO sub_end;
<<err>>
dbms_output.put_line('ERR');
GOTO sub_end;
<<sub_end>>
dbms_output.put_line('Exit');
END;
/
6) 예외처리부
DECLARE
counter INTEGER;
BEGIN
counter := 10;
counter := 10 / 0; -- 예외가 나오는 코드
EXCEPTION WHEN OTHERS THEN -- 예외처리부
dbms_output.put_line('예외가 발생했습니다.'); -- 출력
END;
/
2. varray
: 배열 ( Variable ARRAY )
-- PL에서는 같은 자료형을 가진 배열을 만들어 데이터를 저장할 수 있다.
DECLARE
TYPE varray_test IS VARRAY(3) OF INTEGER;
-- TYPE 타입명 IS VARRAY (배열개수) OF 자료형
-- 3개의 배열, 번지수는 1부터 시작(자바는 0)
-- int varray_test[ ]; 과 같은 의미의 코드
varr varray_test;
-- 변수명 타입
-- varray_test타입의 변수 varr 선언
BEGIN
varr := varray_test(111,222,333);
-- varray_test[] = new int [3] 와 같은 의미
dbms_output.put_line('varr(1) = ' || varr(1));
dbms_output.put_line('varr(2) = ' || varr(2));
dbms_output.put_line('varr(3) = ' || varr(3));
END;
/
3. UI 화면(명령 프롬프트 창) 띄워서 입력값에 따른 결과 띄우기
ACCEPT p_deptno PROMPT '부서번호를 입력하시오(급여의 합)'
-- 프롬프트창 띄워서 입력값 (부서번호)
DECLARE
v_salTotal NUMBER;
BEGIN
-- 쿼리문 작성해서 입력값을 집어 넣는다.
SELECT SUM (salary) INTO v_saltotal
-- select구문은 output(조회한 쿼리)이 있는데, 그 값을 v_saltotal에 집어넣는다는 의미의 코드
-- INTO : select구문의 결과값을 다른 곳으로 넣는 예약어
FROM employees
WHERE department_id = &p_deptno;
-- &는 외부에서 값을 가져온다는 의미
dbms_output.put_line(&p_deptno ||'번 부서의 급여의 합은 '
|| TO_CHAR( v_saltotal, '$999,999,999') || ' 입니다.');
END;
/
-- 예제
-- 사원번호를 입력받고 그 사원의 급여의 1000을 더한 값으로 갱신하시오(update)
-- 그 값을 가져와서 사원번호, 갱신된 급여를 출력하도록 하시오 (SELECT)
ACCEPT p_empid PROMPT '사원번호를 입력하시오(+1000)'
DECLARE
v_sal EMPLOYEES.salary%TYPE := 1000; -- 더할 값(1000)
-- 테이블명.컬럼명%TYPE : 자동적으로 해당 컬럼의 자료형으로 맞춰준다
v_salTotal NUMBER;
BEGIN
-- 업데이트 전 값을 출력하기
SELECT salary INTO v_salTotal
FROM employees
WHERE employee_id = &p_empid;
dbms_output.put_line('사원번호 : ' || &p_empid || ', 급여 : ' || v_salTotal );
-- update
UPDATE employees
SET salary = salary + v_sal
WHERE employee_id = &p_empid;
-- select
-- 가져와서 출력하기
SELECT salary INTO v_salTotal
FROM employees
WHERE employee_id = &p_empid;
dbms_output.put_line('사원번호 : ' || &p_empid || '번 +1000후의 급여 : ' || v_salTotal );
END;
/
4. ROWTYPE
-- 한 테이블의 모든 컬럼 자료형을 가진 변수가 들어가있음
DECLARE
v_empno employees.employee_id%TYPE
-- 또는
v_emp EMPLOYEES%ROWTYPE;
-- EMPLOYEES 테이블의 타입이 모두 들어가있음
-- column 의 이름이 자동적으로 변수명이 된다
-- 한 테이블의 여러 변수타입을 가져오고 싶을때 사용할 수 있음
-- 접근 예 ) v_emp.first_name;
BEGIN
SELECT employee_id, first_name, last_name, salary
INTO v_emp.employee_id, v_emp.first_name, v_emp.last_name, v_emp.salary
-- 이렇게 사용이 가능함 ( 변수 하나씩 모두 선언할 필요 없음)
FROM employees
WHERE employee_id = 100;
dbms_output.put_line('사원번호 : ' || v_emp.employee_id );
dbms_output.put_line('사원이름 : ' || v_emp.first_name );
dbms_output.put_line('사원성 : ' || v_emp.last_name );
dbms_output.put_line('사원급여 : ' || v_emp.salary );
END;
/
-- 예제 2
-- 이름, 급여, 부서번호를 입력받아
-- 사원을 추가하기 (employees 테이블) * job_id = IT_PROG / email : 이름@example.com
-- 부서번호가 30일 경우 -> 입력받은 급여에 20% 인상해서 입력
-- 부서번호가 60일 경우 -> 입력받은 급여에 10% 인상해서 입력
-- 입력처리
ACCEPT p_name PROMPT '이름 : '
ACCEPT p_sal PROMPT '급여 : '
ACCEPT p_deptno PROMPT '부서번호 : '
DECLARE
v_name employees.last_name%TYPE := '&p_name'; -- 문자열일때는 '' 안에 넣어주기
v_sal employees.salary%TYPE := &p_sal;
v_deptno employees.department_id%TYPE := &p_deptno;
v_emp employees%ROWTYPE;
BEGIN
dbms_output.put_line( '입력값 확인하기');
dbms_output.put_line( v_name);
dbms_output.put_line( v_sal);
dbms_output.put_line( v_deptno);
IF v_deptno = 30 THEN v_sal := v_sal * 1.2;
ELSIF v_deptno = 60 THEN v_sal := v_sal *1.1;
END IF;
INSERT INTO employees
VALUES ( EMPLOYEES_SEQ.nextval, null, v_name, v_name||'@example.com',
null, SYSDATE, 'IT_PROG', v_sal, null,null, v_deptno);
-- EMPLOYEES_SEQ.nextval : 다음 시퀀스번호에 맞추어 저장
-- 출력하기
SELECT * INTO v_emp
FROM employees
WHERE last_name = v_name;
dbms_output.put_line( '<입력된 사원>');
dbms_output.put_line( v_emp.employee_id);
dbms_output.put_line( v_emp.last_name);
dbms_output.put_line( v_emp.salary);
dbms_output.put_line( v_emp.email);
dbms_output.put_line( v_emp.department_id);
END;
/
'DB > Oracle' 카테고리의 다른 글
Oracle day 8 - PL : FUNCTION 함수 (0) | 2019.12.20 |
---|---|
Oracle day 8 - PL : Procedure 프로시저 문 & Cursor 커서 (0) | 2019.12.20 |
Oracle day 7 - Index 인덱스 (0) | 2019.12.19 |
Oracle day 7 - view & sequence 문제 (0) | 2019.12.19 |
Oracle day 7 - SEQUENCE 시퀀스 & SYNONYM 동의어 (0) | 2019.12.19 |