< Book Table >

bookid bookname publisher price
1 축구의 역사 굿스포츠 7000
2 축구아는 여자 나무수 13000
3 축구의 이해 대한미디어 22000
4 골프 바이블 대한미디어 35000
5 피겨 교본 굿스포츠 8000
6 역도 단계별기술 굿스포츠 6000
7 야구의 추억 이상미디어 20000
8 야구를 부탁해 삼성당 7500
10 Olympic Champions Pearson 13000

< Cumtomer Table >

custid name address phone
1 박지성 영국 맨체스타 000-5000-0001
2 김연아 대한민국 서울 000-6000-0001
3 장미란 대한민국 강원도 000-7000-0001
4 추신수 미국 클리블랜드 000-8000-0001
5 박세리 대한민국 대전 NULL

< Orders Table >

orderid custid bookid saleprice orderdate
1 1 1 6000 2020-07-01
2 1 3 21000 2020-07-03
3 2 5 8000 2020-07-03
4 3 6 6000 2020-07-04
5 4 7 20000 2020-07-05
6 1 2 12000 2020-07-07
7 4 8 13000 2020-07-07
8 3 10 12000 2020-07-08
9 2 10 7000 2020-07-09
10 3 8 13000 2020-07-10

※ 해당 교재에 해설 및 풀이가 없으므로, 제가 푼 풀이가 틀릴 수도 있습니다.

 

1. 대한민국에 거주하는 고객의 고객명,주소,연락처를 보이는 프로시저를 작성하고 동작됨을 보이시오.

--프로시저 생성
CREATE OR REPLACE PROCEDURE GET_KR_USER_PRC(rc OUT SYS_REFCURSOR) 
AS 
BEGIN 
OPEN rc FOR
   SELECT NAME,
         ADDRESS,
         PHONE
     FROM CUSTOMER c  WHERE ADDRESS LIKE '%대한민국%';
END GET_KR_USER_PRC;

--동작 확인
DECLARE
   rc  SYS_REFCURSOR;
   NAME CUSTOMER.NAME%TYPE;
   ADDRESS CUSTOMER.ADDRESS%TYPE;
   PHONE CUSTOMER.PHONE%TYPE;
BEGIN
   GET_KR_USER_PRC(rc);
   LOOP
    FETCH rc INTO NAME, ADDRESS, PHONE;
    EXIT
     WHEN rc%notfound;
    dbms_output.put_line(NAME || ',' || ADDRESS || ',' || PHONE);
  END LOOP;
END;

 

2. 도서 테이블에 동일도서(출판사,책이름이 동일)가 있으면 도서의 가격만 새롭게 변경하고 그렇지 않으면 새로운 행을 삽입하는 프로시저를 작성하고 동작됨을 보이시오.

--프로시저 생성
CREATE OR REPLACE PROCEDURE BOOK_PRICE_PRC(in_publisher IN BOOK.PUBLISHER%TYPE,
in_bookname IN BOOK.BOOKNAME%TYPE,
in_price BOOK.PRICE%TYPE)
AS d_book_id BOOK.BOOKID%TYPE;
d_max_book_id BOOK.BOOKID%TYPE;
   BEGIN
   BEGIN
   SELECT bookid INTO d_book_id
     FROM BOOK b  
    WHERE b.BOOKNAME = in_bookname
      AND b.PUBLISHER = in_publisher;
   EXCEPTION
    WHEN NO_DATA_FOUND THEN
       d_book_id := 0;
    END;
   BEGIN
    SELECT MAX(bookid)+1 INTO d_max_book_id
     FROM BOOK b;
   EXCEPTION
    WHEN NO_DATA_FOUND THEN
       d_max_book_id := 1;
   END;
   IF(d_book_id = 0)THEN
      INSERT INTO BOOK (BOOKID, BOOKNAME, PUBLISHER, PRICE)
      VALUES(d_max_book_id, in_bookname, in_publisher, in_price);
   ELSE
      UPDATE BOOK
      SET  PRICE=in_price
      WHERE BOOKID=d_book_id;
   END IF;
END BOOK_PRICE_PRC;

--동작 확인
SELECT * FROM BOOK;
call BOOK_PRICE_PRC('test3','test2',4000);
call BOOK_PRICE_PRC('대한미디어','축구의 이해',1000);
SELECT * FROM BOOK;

 

3. 특정 고객의 주문 총액을 계산하여 3만원 이상이면 ‘우수’, 3만원 미만이면 ‘일반’을 반환하는 함수 grade()를 작성하고 동작됨을 보이시오.

CREATE OR REPLACE FUNCTION grade(v_custid NUMBER)
    RETURN VARCHAR
IS
    v_grade varchar(100);
BEGIN
   SELECT CASE WHEN SUM(o.SALEPRICE) >= 30000
         THEN '우수'
         ELSE '일반'
         END INTO v_grade
      FROM ORDERS o 
    WHERE o.CUSTID=v_custid;

  RETURN v_grade;
END;

SELECT grade(2) AS grade
FROM dual;

 

4. 3번문에에서 작성한 사용자정의 함수 grade()를 호출하여 고객의 이름과 등급을 보이는 SQL문을 작성하고 실행결과를 보이시오.

SELECT c.NAME,
      grade(c.CUSTID) AS grade
  FROM CUSTOMER c;

 

 5. 고객별로 도서를 몇 권 구입 했는지와 총구매액을 보이는 프로시저를 작성하고 동작됨을 보이시오.

 --프로시저 생성
CREATE OR REPLACE PROCEDURE GET_BOOK_ORDER_BYCUST_PRC(rc OUT SYS_REFCURSOR) 
AS 
BEGIN 
OPEN rc FOR
   SELECT o.CUSTID,
        COUNT(1) AS BOOK_COUNT,
        SUM(o.SALEPRICE) AS SALEPRICE 
   FROM ORDERS o 
  GROUP BY o.CUSTID ;
END GET_BOOK_ORDER_BYCUST_PRC;

--동작 확인
DECLARE
   rc  SYS_REFCURSOR;
   BOOK_COUNT number;
   CUSTID number;
   SALEPRICE number;
BEGIN
   GET_BOOK_ORDER_BYCUST_PRC(rc);
   LOOP
    FETCH rc INTO CUSTID, BOOK_COUNT, SALEPRICE;
    EXIT
     WHEN rc%notfound;
    dbms_output.put_line(CUSTID || ',' || BOOK_COUNT || ',' || SALEPRICE);
  END LOOP;
END;

 

6. 고객이 주문한 내용의 변경이 발생할 경우 로그테이블에 변경전 변경후 데이터를 기록하는 트리거를 작성하고 동작됨을 보이시오.

CREATE TABLE ORDERS_LOG
   (   
    "NO" NUMBER(10,0) PRIMARY KEY,
    "ORDERID" NUMBER(2,0), 
   "BEFORE_CUSTID" NUMBER(2,0), 
   "AFTER_CUSTID" NUMBER(2,0), 
   "BEFORE_BOOKID" NUMBER(2,0), 
   "AFTER_BOOKID" NUMBER(2,0), 
   "BEFORE_SALEPRICE" NUMBER(8,0), 
   "AFTER_SALEPRICE" NUMBER(8,0), 
   "BEFORE_ORDERDATE" DATE,
   "AFTER_ORDERDATE" DATE,
   "UPDATE" DATE
   ) ;
  
  --시퀀스 생성 
CREATE SEQUENCE ORDERS_LOG_NO_SEQ INCREMENT BY 1 MINVALUE 0 NOCYCLE NOCACHE NOORDER;

--트리거 생성
CREATE OR REPLACE TRIGGER c##sql3.ORDERS_UPDATE
AFTER UPDATE 
ON ORDERS
FOR EACH ROW
BEGIN
   INSERT INTO ORDERS_LOG
   (
   "NO", 
   ORDERID, 
   BEFORE_CUSTID, 
   AFTER_CUSTID, 
   BEFORE_BOOKID, 
   AFTER_BOOKID, 
   BEFORE_SALEPRICE, 
   AFTER_SALEPRICE, 
   BEFORE_ORDERDATE, 
   AFTER_ORDERDATE, 
   "UPDATE")
   VALUES(
   ORDERS_LOG_NO_SEQ.nextval, 
   :OLD.ORDERID, 
   :OLD.CUSTID, 
   :NEW.CUSTID, 
   :OLD.BOOKID, 
   :NEW.BOOKID, 
   :OLD.SALEPRICE, 
   :NEW.SALEPRICE, 
   :OLD.ORDERDATE, 
   :NEW.ORDERDATE, 
   SYSDATE);
END;

UPDATE ORDERS
SET CUSTID=5, BOOKID=6, SALEPRICE=13000, ORDERDATE=TIMESTAMP '2022-07-03 00:00:00.000000'
WHERE ORDERID=11;

SELECT * FROM ORDERS_LOG;

 

7. 그룹함수를 이용하여 출판사별 고객별 판매액을 소계와 총계가 보이도록 DML문을 작성하고 실행해 보이시오. 

SELECT b.PUBLISHER, o.CUSTID, SUM(o.SALEPRICE) AS PRICE
  FROM ORDERS o 
  LEFT JOIN BOOK b ON o.BOOKID = b.BOOKID 
 GROUP BY ROLLUP(b.PUBLISHER, o.CUSTID) ;

 

 8. 윈도우 함수를 이용하여 출판사별 총판매금액, 판매순위를 산출하는 DML문 작성하고 실행해 보이시오.

SELECT b.PUBLISHER, SUM(o.SALEPRICE) AS PRICE,
RANK() OVER (ORDER BY SUM(o.SALEPRICE) DESC) AS RANKING
  FROM ORDERS o 
  LEFT JOIN BOOK b ON o.BOOKID = b.BOOKID 
 GROUP BY b.PUBLISHER ;


Reference : 오라클로 배우는 데이터베이스 개론과 실습

https://www.hanbit.co.kr/store/books/look.php?p_code=B2082711299

 

IT CookBook, 오라클로 배우는 데이터베이스 개론과 실습(2판)

데이터베이스 핵심 이론을 오라클로 실습하며 공부할 수 있는 책이다. 데이터베이스 시스템을 이해하는 데 필요한 이론을 4개의 부로 나누어 실습과 함께 익힌 다음, 마지막에는 워크북으로 배

www.hanbit.co.kr


 

'SQL' 카테고리의 다른 글

SQL 문제 및 풀이  (0) 2023.06.05
SQL 연습 문제 ②  (0) 2023.06.01
SQL 연습 문제 ①  (0) 2023.06.01
SQL 연습 문제(中)  (0) 2023.06.01
SQL 문제 연습(下)  (0) 2023.06.01

+ Recent posts