DataBase

2022-12-01 데이터 베이스 오라클 SQL : 프로시져(Procedure)

헤니s 2022. 12. 1. 17:45

Stored Procedure :  Procedure

 

 - 특정 결과를 산출할 수 있는 모듈을 작성하고 컴파일하여 서버의 프로시져 캐쉬에 저장하여 사용
 - 모든 응용프로그램에서 사용할 수 있도록 캡슐화 기능 제공 => 일관성 제공
 - 데이터베이스 내부 구조에 대한 보안성 제공 -- 뷰... 구조를 사용자가 모르고 결과값만 반환
 - 프로시져는 반환 값이 없음

 

※ function 과 procedure

procedure : procedure  이름을 통한 반환.

  -  procedure 값을 내보낼수 있음. ' out '이라는 매개변수 사용

function  : 함수명을 통해서 결과가 반환됨.

 

모듈화 : 특정한 기능의 모음을 보관

응용프로그램에 의해서 내부 값이 변경될 수 없음

 

(사용형식)

   CREATE [OR REPLACE] PROCEDURE 프로시져명[(
     매개변수 [IN|OUT|INOUT] 데이터타입[:=디폴트 값],--데이터타입 크기는 쓰지말자
                   :
     매개변수 [IN|OUT|INOUT] 데이터타입[:=디폴트 값])
   IS|AS
      선언영역
   BEGIN
      실행역역
   END;

    -- 매개변수 : 프로시져를 수행하기 위해 필요함.
    -- 매개변수가 in 입력용 / out 출력용 / 
    -- inout 둘다가능 = 컴파일할때 결정불가 / 실행할때 결정(DBMS 부담으로 사용자제)
    -- [IN|OUT|INOUT] 생략가능하면 in으로 취급함
    
-- 데이터를 정의하지 않고 프로시져를 호출했을 때 자동으로 입력하는 디폴트 => 사용자제

 

수행예) 직무코드,직무명,최대급여,최소급여를 입력 받아 HR계정의 JOBS테이블에 신규 데이터를
       삽입하는 프로시져를 작성하시오.
 

CREATE OR REPLACE PROCEDURE insert_jobs_proc(
      p_job_id IN HR.JOBS.JOB_ID%TYPE,
      p_job_title IN HR.JOBS.JOB_TITLE%TYPE,
      p_misal IN NUMBER,
      p_mxsal IN NUMBER)
   IS -- (변수 필요없음)
   BEGIN
     INSERT INTO HR.JOBS VALUES(p_job_id,p_job_title,p_misal,p_mxsal);
     COMMIT;
   END;


   
[프로시져의 실행]
 1. 독립적 실행 -- 프로시져에 전달할 값만 기술해준다.
-- OUT 매개변수를 사용하지 않은 경우
-- 프로시져는 셀렉트문에 실행될수 없다. / 독립적 실행뿐... 
   EXEC|EXECUTE 프로시져명(매개변수list); 
   
 2. PL/SQL의 블록에서 실행 -- 변수 사용할 경우
  - OUT 매개변수를 사용한 경우 - OUT매개변수에 의해 전달되는 값을 보관한 변수를 사용 
-- 다른 프로시져나 다른함수 사용 할때 EXEC|EXECUTE 사용안함
-- OUT매개변수가 아니여도 필요에 의해 값을 저장할수 있는 변수 사용
    프로시져명(매개변수list)
    
 

EXECUTE insert_jobs_proc('sample1','SAMPLE JOB TITLE',3000,5000);


       
사용예)직무코드를 입력받아 해당 자료를 JOBS테이블에서 삭제하는 프로시져 작성

 CREATE OR REPLACE PROCEDURE delect_jobs_proc(
    p_job_id IN JOBS.JOB_ID%TYPE)
  IS
    L_CNT NUMBER:=0;
  BEGIN--삭제는 데이터가 있어야 삭제가 된다. 해당 자료의 존재유무 확인
    SELECT COUNT(*) INTO L_CNT
      FROM JOBS
     WHERE JOB_ID=p_job_id; -- 찾은 자료를 L_CNT에 넣어줌
     
    IF L_CNT!=0 THEN
       DELETE FROM JOBS WHERE JOB_ID=p_job_id;
    ELSE 
       DBMS_OUTPUT.PUT_LINE('해당자료가 테이블에 없습니다..');
    END IF;
    COMMIT;
  END;
  
  EXEC delect_jobs_proc('sample1');

 

 

사용예)오늘이 2020년 7월 28일이라고 가정하고 매출정보를 장바구니에 저장하는 프로시져를 작성하시오
      입력값은 회원번호,오늘날짜,상품코드, 수량이다.

       
   CREATE OR REPLACE PROCEDURE insert_cart_proc(
     p_mid IN MEMBER.MEM_ID%TYPE,
     p_date IN DATE,
     p_pid IN PROD.PROD_ID%TYPE,
     p_qty IN NUMBER)
  IS
     L_CART_NO CART.CART_NO%TYPE;
     L_FLAG CHAR(9):=TO_CHAR(p_date,'YYYYMMDD')||'%';
     L_CNT NUMBER:=0;
  BEGIN
     SELECT COUNT(*) INTO L_CNT
       FROM CART
      WHERE CART_NO LIKE L_FLAG;
      
     IF L_CNT=0 THEN
        L_CART_NO:=TO_CHAR(p_date,'YYYYMMDD')||TRIM('00001');
     ELSE
        SELECT MAX(CART_NO)+1 INTO L_CART_NO
          FROM CART
         WHERE CART_NO LIKE L_FLAG;
    END IF;
    INSERT INTO CART VALUES(p_mid,L_CART_NO,p_pid,p_qty);
    COMMIT;
  END;
    
    
      EXECUTE insert_cart_proc('a001',TO_DATE('20200728'),'P201000008',5);

 


사용예) 회원번호와 년도를 입력받아 해당회원의 구매금액합계를 반환받는 프로시져를 작성
입력 2개. 출력 1개

 

CREATE OR REPLACE PROCEDURE sum_cart_proc(
       p_mid IN MEMBER.MEM_ID%TYPE,
       p_year IN CHAR,
       p_sum OUT NUMBER) -- OUT매개변수 선언
    IS
      L_FLAG CHAR(5):=P_YEAR||'%'; 
      --LIKE 미리결합시켜서 사용할수도...
    BEGIN
      SELECT SUM(A.CART_QTY*B.PROD_PRICE) INTO p_sum -- OUT 매개변수로 선언한 값이 자동으로 들어옴
        FROM CART A, PROD B
       WHERE A.CART_PROD=B.PROD_ID
         AND A.CART_NO LIKE L_FLAG
         AND A.CART_MEMBER=p_mid; -- 특정회원으로 제한
    END;

-- Procedure SUM_CART_PROC이(가) 컴파일되었습니다.
-- 실행 : 실행문은 블럭 내부에 있어야 함.

 

 

[실행]

 DECLARE
       L_SUM NUMBER:=0; -- 구매금액합계를 보관할 변수
       L_NAME MEMBER.MEM_NAME%TYPE;
    BEGIN
       SELECT MEM_NAME INTO L_NAME
         FROM MEMBER
        WHERE MEM_ID='c001';
      sum_cart_proc('c001','2020',L_SUM); -- 회원번호,년도, L_SUM <= p_sum
      DBMS_OUTPUT.PUT_LINE('c001, '||L_NAME||' => '||L_SUM);
    END;
    
    ---------------------------------------------------------------
    c001, 신용환 => 19212000

-- 독립실행이 아닌경우 EXECUTE는 안쓴다. // 독립실행이 아닐 땐 프로시져 이름만 쓴다.
-- OUT은 프로시져 안에서 계산된 것을 프로시져 밖으로 꺼내기 위해 사용

 


사용예) 거주지를 입력받아 CUSTOMERS 테이블에서 해당 거주지를 가진 회원정보를 삭제하고
       삭제한 회원의 수를 반환하는 프로시져를 작성하시오

 

-- 프로시져는 반환값이 없다. 반환을 하려면 매개변수가 필요하다.

   

 CREATE OR REPLACE PROCEDURE delete_cust_proc(
     p_add  char, p_cnt  OUT NUMBER)
     IS   
     BEGIN
       SELECT COUNT(*) INTO p_cnt
         FROM CUSTOMERS
        WHERE MEM_ADD1 LIKE p_add||'%';  --입력받은 거주지의 숫자를 COUNT한걸 p_cnt에 넣는다.
      
       DELETE FROM CUSTOMERS
        WHERE MEM_ADD1 LIKE p_add||'%';  --입력받은 거주지와 맞는 사람 삭제
     END;


   
[실행] -- OUT매개변수를 받으려면 변수가 필요하다./EXECUTE 안씀 

ACCEPT P_ADDRESS PROMPT '삭제할 거주지명 입력 : '
   DECLARE
      L_CNT NUMBER:=0;  -- L_CNT는 p_cnt에서 전달받은 것
   BEGIN
      delete_cust_proc('&P_ADDRESS',L_CNT);
  
      DBMS_OUTPUT.PUT_LINE('&P_ADDRESS'||'에 거주한 회원 '||L_CNT||'명의 정보를 삭제함');
  END;

-------------------------------------------------------------
서울에 거주한 회원 1명의 정보를 삭제함