정리

Oracle/OracleDB_SQL 2016. 6. 7. 21:37


**************************************************************
**Parameter가 포함된 Cursor
**************************************************************


cursor cursor_name.. (parameter name, type *type의 크기는 지정x)


SET serveroutput ON
DECLARE
CURSOR c_emp_cursor (deptid number)
IS
SELECT employee_id, last_name
FROM employees
WHERE department_id=deptid;

v_emp_record c_emp_cursor%ROWTYPE;
BEGIN
OPEN c_emp_cursor(10);
LOOP
  FETCH c_emp_cursor into v_emp_record;
  EXIT
  WHEN c_emp_cursor%notfound;
  DBMS_OUTPUT.PUT_LINE(v_emp_record.employee_id|| ' ' ||
  v_emp_record.last_name);
  end loop;
  close c_emp_cursor;
  END;
  /

**************************************************************
**Parameter가 포함된 Cursor( for문으로 변경)
**************************************************************
SET serveroutput ON
DECLARE
  CURSOR c_emp_cursor (deptid NUMBER)
  IS
    SELECT employee_id, last_name FROM employees WHERE department_id=deptid;
  v_emp_record c_emp_cursor%ROWTYPE;
BEGIN
 
  FOR v_emp_record IN c_emp_cursor(10)
  LOOP
  -- WHEN c_emp_cursor%notfound;
   DBMS_OUTPUT.PUT_LINE(v_emp_record.employee_id|| ' ' || v_emp_record.last_name);
   END LOOP;
END;
/

**************************************************************
**Parameter가 포함된 Cursor( for문으로 변경)
**************************************************************
****80,60 SA_REP, IT_PROG의 모든 사원을 출력


SET SERVEROUTPUT ON
DECLARE
 CURSOR c_emp_cursor(deptid NUMBER, job_id VARCHAR2)
 IS
 SELECT employee_id,department_id, last_name,job_id
 FROM employees
 WHERE department_id=deptid AND job_id='SA_REP';
 
 v_emp_record c_emp_cursor%ROWTYPE;
 
 BEGIN
 FOR v_emp_record IN c_emp_cursor(80,'SA_REP')
 LOOP
  DBMS_OUTPUT.PUT_LINE(v_emp_record.department_id|| ' ' || v_emp_record.last_name||' '||
  v_emp_record.job_id|| ' ' ||v_emp_record.employee_id);
  END LOOP;
  FOR v_emp_record IN c_emp_cursor(60,'IT_PROG')
  LOOP
    DBMS_OUTPUT.PUT_LINE(v_emp_record.department_id|| ' ' || v_emp_record.last_name||' '||
  v_emp_record.job_id|| ' ' ||v_emp_record.employee_id);
   END LOOP;
END;
/

**************************************************************
***WHERE CURRENT OF 절
**************************************************************
WHERE CURRENT OF절을 쓰지 않으면 모두가 바뀐다.

** WHERE CURRENT OF 절을 사용한 경우

SET SERVEROUTPUT ON
DECLARE
CURSOR c_emp_cursor
IS
SELECT employee_id, salary
FROM employees
WHERE department_id=20 FOR UPDATE NOWAIT;

BEGIN
FOR emp_record IN c_emp_cursor
LOOP
    UPDATE employees SET salary=10 WHERE CURRENT OF c_emp_cursor;
END LOOP;
END;
/


** WHERE CURRENT OF 절을 사용하지 않은 경우

 


**************************************************************
** 예외 처리
**************************************************************

SET serveroutput ON
DECLARE
  v_lname VARCHAR2(15);
  BEGIN
  SELECT last_name INTO v_lname
  FROM employees
  WHERE department_id=20;
 
   DBMS_OUTPUT.PUT_LINE('John' ' s last_name is : ' || v_lname);

  EXCEPTION
    WHEN TOO_MANY_ROWS THEN
    DBMS_OUTPUT.PUT_LINE(' Your select statement retrieved
    multiple rows. Consider using a cursor.');
    END;
    /

 

미리 정의된 오라클 오류 트랩
- NO_DATA_FOUND
- TOO_MANY_ROWS
- INVALID_CURSOR
- ZERO_DIVIDE
- DUP_VAL_ON_INDEX


***********************************************************
-- first_name이 'E'로 시작하는 사원 출력
-- 데이터가 없으면 해당사원이 없습니다.
-- 데이터가 두 건 이상이면 사원이 두 명 이상입니다.
***********************************************************

SET serveroutput ON
DECLARE
  v_fname employees.first_name%type;
  BEGIN
        SELECT first_name INTO v_fname FROM employees
        WHERE first_name LIKE 'E%';
       
        DBMS_OUTPUT.PUT_LINE('E인 이름 :' ||v_fname);
        EXCEPTION
        WHEN NO_DATA_FOUND THEN
          DBMS_OUTPUT.PUT_LINE('해당 사원이 없다.');
        WHEN TOO_MANY_ROWS THEN
        DBMS_OUTPUT.PUT_LINE('사원이 두 명 이상');
        END;
        /

**************************************************************
** 미리 정의되지 않은 오류 트랩
**************************************************************

 

**************************************************************
** 예외 트랩에 대한 함수
**************************************************************
SQLCODE : 오류 코드에 대한 숫자 값을 반환
SQLERRM : 오류 번호와 연관된 메시지를 반환

create table t_pragma(no number primary key, name varchar2(10));

insert into t_pragma values(1,'aaa');

SET serveroutput ON
DECLARE
  new_msg exception;
  pragma exception_init(new_msg, -1);
  BEGIN
  insert into t_pragma values(1,'CCC');
  exception
  WHEN new_msg THEN
  DBMS_OUTPUT.PUT_LINE('존재하는 번호입니다.');
END;
/
*******************************************************************************
** 함수에 다른 값을 넣어버리면
오류 보고 -
ORA-00001: 무결성 제약 조건(EXPERT.SYS_C0011176)에 위배됩니다
ORA-06512:  5행
00001. 00000 -  "unique constraint (%s.%s) violated"
*Cause:    An UPDATE or INSERT statement attempted to insert a duplicate key.
           For Trusted Oracle configured in DBMS MAC mode, you may see
           this message if a duplicate entry exists at a different level.
*Action:   Either remove the unique restriction or do not insert the key.
이러한 오류메세지가 뜬다.


SET serveroutput ON
DECLARE
  new_msg exception;
  pragma exception_init(new_msg, -2);
  BEGIN
  insert into t_pragma values(1,'CCC');
  exception
  WHEN new_msg THEN
  DBMS_OUTPUT.PUT_LINE('존재하는 번호입니다.');
END;
/
*********************************************************************************
오라클 레퍼런스 사이트
http://docs.oracle.com/en/database/database.html
-> Oracle Database 11g Release 2(11.2) 선택
-> Administerng 선택
-> Error Message 선택


*********************************************************************************
*** Oracle 서버 오류 01400("cannot insert NULL")을 트랩하려면..
*********************************************************************************


SET serveroutput ON
DECLARE
    e_insert_excep EXCEPTION;
    PRAGMA EXCEPTION_INIT(e_insert_excep, -01400);
   
BEGIN
INSERT INTO departments
(department_id, department_name) VALUES (280, NULL);
EXCEPTION
 WHEN e_insert_excep THEN
    DBMS_OUTPUT.PUT_LINE('INSERT OPERATION FAILED');
    DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/


INSERT OPERATION FAILED
ORA-01400: NULL을 ("EXPERT"."DEPARTMENTS"."DEPARTMENT_NAME") 안에 삽입할 수 없습니다

 

 

 

 

 

*********************************************************************************
*** ERROR 함수 사용하기
*********************************************************************************

create table errors(err_num number(20), err_msg VARCHAR2(100));

SET SERVEROUTPUT ON

DECLARE
    new_msg exception;
    pragma exception_init(new_msg, -1);
    err_num number;
    err_msg varchar2(255);
BEGIN
    INSERT into t_pragma values(1,'CCC');
exception
WHEN new_msg THEN
DBMS_OUTPUT.PUT_LINE('존재하는 번호 입니다.');
err_num := SQLCODE;
err_msg := substr(SQLERRM, 1, 100);
insert into errors values(err_num,err_msg);
END;
/

 

 

9장
SYS @ prod > select owner, object_name, object_type
  2  from dba_objects
  3  where object_type='PROCEDURE';


show error를 입력하면 error를 확인한다.


*********************************************************************************
*** Procedure 생성 IN 파라미터 모드
*********************************************************************************

EXPERT @ prod > CREATE OR REPLACE
  2  PROCEDURE raise_salary
  3  (p_id            IN employees.employee_id%TYPE,
  4  p_percent          IN NUMBER)
  5  IS
  6  BEGIN
  7  UPDATE employees SET salary=salary*(1+p_percent/100) WHERE employee_id=p_id;
  8  END raise_salary;
  9  /

Procedure created.

EXPERT @ prod > excute raise_salary(206,10);
SP2-0734: unknown command beginning "excute rai..." - rest of line ignored.
EXPERT @ prod > execute raise_salary(206,10);

PL/SQL procedure successfully completed.

EXPERT @ prod > select employee_id, salary
  2  from employees
  3  where employee_id=206;

EMPLOYEE_ID     SALARY
----------- ----------
        206       9130

EXPERT @ prod > select text from user_source
  2  where name='RAISE_SALARY'
  3  /
--> 만들어진 구문을 볼 수 있다.
TEXT
--------------------------------------------------------------------------------
PROCEDURE raise_salary
(p_id            IN employees.employee_id%TYPE,
p_percent               IN NUMBER)
IS
BEGIN
UPDATE employees SET salary=salary*(1+p_percent/100) WHERE employee_id=p_id;
END raise_salary;

7 rows selected.


*********************************************************************************
*** Procedure 생성 OUT 파라미터 모드
*********************************************************************************


EXPERT @ prod > CREATE OR REPLACE
  2  PROCEDURE query_emp
  3  (p_id IN employees.employee_id%TYPE,
  4  p_name OUT employees.last_name%TYPE,
  5  p_salary OUT employees.salary%TYPE)
  6  IS
  7  BEGIN
  8  SELECT last_name,
  9  salary INTO p_name, p_salary FROM employees
 10  WHERE employee_id=p_id;
 11  END query_emp;
 12  /

Procedure created.

EXPERT @ prod > SET SERVEROUTPUT ON
EXPERT @ prod > DECLARE
  2  v_emp_name employees.last_name%TYPE;
  3  v_emp_sal employees.salary%TYPE;
  4  BEGIN
  5  query_emp(206,v_emp_name, v_emp_sal);
  6  DBMS_OUTPUT.PUT_LINE(v_emp_name || ' earns ' || to_char(v_emp_sal, '$999,999,00'));
  7  END;
  8  /
Gietz earns       $91,30

PL/SQL procedure successfully completed.

 

*********************************************************************************
*** Procedure 생성 IN OUT 파라미터 모드
*********************************************************************************


EXPERT @ prod > show errors;
No errors.
EXPERT @ prod > CREATE OR REPLACE
  2  PROCEDURE format_phone
  3  (p_phone_no IN OUT VARCHAR2)
  4  IS
  5  BEGIN
  6  p_phone_no :='('||SUBSTR(p_phone_no,1,3)||SUBSTR(p_phone_no,4,4)||'-'||SUBSTR(p_phone_no,8);
  7  END format_phone;
  8  /

Procedure created.

EXPERT @ prod > variable b_phone_no varchar2(15)
EXPERT @ prod > execute :b_phone_no := '01079799292'

PL/SQL procedure successfully completed.

EXPERT @ prod > print b_phone_no

B_PHONE_NO
--------------------------------
01079799292

EXPERT @ prod > execute format_phone (:b_phone_no)

PL/SQL procedure successfully completed.

EXPERT @ prod > print b_phone_no

B_PHONE_NO
--------------------------------
(0107979-9292

EXPERT @ prod >

 

*********************************************************************************
*** FUNCTION 생성 예제1
*********************************************************************************


EXPERT @ prod > CREATE OR REPLACE
  2  FUNCTION get_sal
  3  (p_id employees.employee_id%TYPE)
  4  RETURN NUMBER
  5  IS
  6  v_sal employees.salary%TYPE:=0;
  7  BEGIN
  8  select salary into v_sal from employees where employee_id = p_id;
  9  RETURN v_sal;
 10  END get_sal;
 11  /

Function created.

EXPERT @ prod > set serveroutput ON
EXPERT @ prod > execute DBMS_OUTPUT.PUT_LINE(get_sal(100));
24000

PL/SQL procedure successfully completed.

EXPERT @ prod > set serveroutput ON
EXPERT @ prod > DECLARE
  2  sal employees.salary%TYPE;
  3  BEGIN
  4  sal:=get_sal(100);
  5  DBMS_OUTPUT.PUT_LINE('The salary is: ' || sal);
  6  END;
  7  /
The salary is: 24000

PL/SQL procedure successfully completed.


*********************************************************************************
*** SQL 표현식에 함수 사용
*********************************************************************************


EXPERT @ prod > CREATE OR REPLACE
  2  FUNCTION tax
  3  (p_value IN NUMBER)
  4  RETURN NUMBER
  5  IS
  6  BEGIN
  7  RETURN (p_value*0.08);
  8  END tax;
  9  /

Function created.

EXPERT @ prod > select employee_id,
  2  last_name, salary, tax(salary) from employees
  3  where department_id=50;

EMPLOYEE_ID LAST_NAME                     SALARY TAX(SALARY)
----------- ------------------------- ---------- -----------
        124 Mourgos                         5800         464
        141 Rajs                            4300         344
        142 Davies                          3900         312
        143 Matos                           3400         272
        144 Vargas                          3300         264

 

*********************************************************************************
*** 패키지
*********************************************************************************

- 선언부
EXPERT @ prod > CREATE OR REPLACE
  2  PACKAGE emp_total
  3  AS
  4  PROCEDURE emp_sum;
  5  PROCEDURE emp_avg;
  6  END emp_total;
  7  /

Package created.

- 몸체부
EXPERT @ prod > create or replace package body emp_total
  2  as
  3  procedure emp_sum
  4  is
  5  cursor emp_total_sum
  6  is
  7  select count(*), sum(salary) from employees;
  8  total_num number;
  9  total_sum number;
 10  BEGIN
 11  open emp_total_sum;
 12  fetch emp_total_sum into total_num, total_sum;
 13  DBMS_OUTPUT.PUT_LINE('총 인원수 : '||total_num||',급여합계:'||total_sum);
 14  close emp_total_sum;
 15  end emp_sum;
 16  procedure emp_avg
 17  is
 18  cursor emp_total_avg
 19  is
 20  select count(*), avg(nvl(salary,0)) from employees;
 21  total_num number;
 22  total_avg number;
 23  BEGIN
 24  open emp_total_avg;
 25  fetch emp_total_avg into total_num, total_avg;
 26  DBMS_OUTPUT.PUT_LINE('총인원수:'||total_num||',급여평균:'||total_avg);
 27  close emp_total_avg;
 28  end emp_avg;
 29  end emp_total;
 30  /

Package body created.

 

 

'Oracle > OracleDB_SQL' 카테고리의 다른 글

Trigger  (0) 2016.06.08
PL/SQL 소개  (0) 2016.06.02
오라클 구조 파일보기  (0) 2016.05.31
View  (0) 2016.05.30
유저 액세스 제한  (0) 2016.05.27
admin