190504_DAY39 <복습> <바인드변수>

<Rollup & Cube> <카티션 곱> <집합연산자>


<저장 프로시저>

  • 자주 사용되는 DML, SQL을 모듈화(독립적인 객체)

  • 서로 연관있는 DQL, DML을 연결해서 실행하는 단위

    CREATE OR REPLACE PROCEDURE 프로시저명(바이트정의없는 변수선언 v2 VARCHAR2)
    IS
        --변수선언;
        v VARCHAR2(15);
    BEGIN
        조건문(IF문, IF ELSE문, IF~ELSIF~ELSE), 반복문(LOOP, FORLOOP, WHILELOOP)
        SQL문1;
        SQL문2;
        SQL문3;
    END;
    /
    사용법)
    1. CREATE PROCEDURE ~ (프로시저를 DB에 저장) 이후 @test.sql로 실행
    2. EXEC[UTE] 프로시저명();
    2-1.EXEC[UTE] 프로시저명(데이터);
        VARIABLE 변수명 자료형;
    2-2.EXEC[UTE] 프로시저명(데이터, :변수명);
    3. PRINT 변수명 

<저장함수>

  • CREATE OR REPLACE FUNCTION 함수명(바이트 정의 없는 변수선언)
    RETURN 자료형
    IS
        --변수선언
        v VARCHAR2(15);
    BEGIN
        조건문(IF문, IF ELSE문, IF~ELSIF~ELSE), 반복문(LOOP, FORLOOP, WHILELOOP)
        SQL문1;
        SQL문2;
        SQL문3;
    END;
    /
    
  • 사용법

    사용법)
    1. CREATE FUNCTION ~ (함수를 DB에 저장) 이후 @test.sql로 실행
    2. VARIABLE 바이드변수명 자료형;
    3. EXEC[UTE] : 바이드변수 := 함수명();
    4. PRINT 변수명 
  • 문제

    문제)
    부서테이블(DEPT)에 정보를 모두(모든행) 출력하시오 --> PL/SQL 사용
    DECLARE
        vdeptno NUMBER(2);
        vdname VARCHAR2(15);
        vloc VARCHAR2(15);
    BEGIN
        SELECT deptno, dname, loc INTO vdeptno, vdname, vloc
        FROM dept;
    
        dbms_output.put_line('부서번호 / 부서명 / 부서위치');
        dbms_output.put_line(vdeptno || '/' || vdname || '/' || vloc);
    END;
    /
    
    --실행하면
    --ORA-01422: exact fetch returns more than requested number of rows
    --에러발생 실제 인출은 요구된것 (1행) 보다 많은 수의 행(2행이상)을 추출합니다
    --조회(select) 결과가 2개 이상일 때 에러 발생
    --해결 Cursor사용 또는 Loop 사용

<Cursor.> 커서

  • select의 결과가 2개행 이상일 때 명시적 사용

  • 2개 행 이상을 출력하는 SELECT문을 저장하는 변수!

  • 형식

    DECLARE
        -- 변수선언, 커서(SELECT문 저장하는 객체라고 생각하면 됨) 정의
        CURSOR 커서명 IS SELECT문장;
    BEGIN
        -- 커서사용
        OPEN 커서명;
            FETCH 커서명 INTO 변수명; -- FETCH는 인출, 데이터를 뽑아온다. 데이터1행 인출!
    
        CLOSE 커서명;
    END;
    /
    
    --=====================================================================================
    DECLARE
        CURSOR cur IS SELECT deptno, dname, loc FROM dept;
            --  변수명 테이블명.컬럼명%type; ==> 특정테이블의 컬럼에 정의된 자료형 참조!
            --  변수명 테이블명%rowtype; ==> 특정 테이블이 갖는 모든 컬럼에 정의된 자료형 참조!
        vdept dept%ROWTYPE; -- %rowtype(테이블타입 - 테이블을 구성하는 모든 컬럼!)
    
    BEGIN
        OPEN cur;
            dbms_output.put_line('부서번호 / 부서명 / 부서위치');
        LOOP
            FETCH cur INTO vdept; --vdept : deptno, dname, loc(==dept테이블)
                EXIT when cur%NOTFOUND; -- 커서를 통해 인출된 행이 없다면
            dbms_output.put_line( vdept.deptno || '/' || vdept.dname || '/' || vdept.loc);
        END LOOP; --이건 while true랑 같은거임
    
    
  CLOSE cur;

END;
/


- 문제

  ```sql
  문제)
  특정 부서에 있는 사원의 사원번호, 사원명, 급여, 입사일을 출력하는 프로시저를 작성하시오
  --> 프로시저명 : dept_member(부서번호)
  --> 커서에 for문 적용 : open, getch, close 생략하는것이 가능
  -- 예 ) for vemp in cur

  DECLARE
      CURSOR cur IS SELECT empno, ename, sal, hiredate FROM emp;
      vemp emp%ROWTYPE;

  BEGIN
      DBMS_OUTPUT.PUT_LINE('사원번호 / 사원명 / 급여 / 입사일');
      FOR vemp in cur

      LOOP
          DBMS_OUTPUT.PUT_LINE('사원번호 : '||vemp.empno || ' 사원명 : '|| vemp.ename || ' 급여 : '|| vemp.sal || ' 입사일 : '|| vemp.hiredate);
      END LOOP;
  END;
  /

  --================================================
  CREATE OR REPLACE PROCEDURE dept_member(vdeptno emp.deptno%type)
  IS
      CURSOR cur
       is
       select empno, ename, sal, to_char( hiredate, 'yyyy"년 "mm"월 "dd"일"') hiredate
       from   emp
       where  deptno=vdeptno;

       cnt number := 0;
    begin

         dbms_output.put_line('< '||vdeptno||' 번 부서 >');
       dbms_output.put_line('사원번호/사원명/급여/입사일');
       dbms_output.put_line('-----------------------------------');

       for vemp in cur   -- cur의 실행결과의 행 수만큼 반복!!
       --    <-----cur에 정의된 select 실행후 한 행 리턴
       loop
           dbms_output.put_line(vemp.empno||' / '||vemp.ename||' / '||
                          vemp.sal||' / '||vemp.hiredate);
       cnt := cnt+1;
       end loop;

        dbms_output.put_line(cnt||'명의 사원이 있어요');
    end;
    /

<Package.> 패키지

  • 동일한 프로시저명 또는 함수명을 구분( NameSpace개념)

    ---------------------패키지 선언---------------------
    CREATE OR REPLACE PACKAGE 패키지명
    IS
        정의될 저장프로시저와 저장함수
    END;
    /
    ---------------------패키지 실행(body)---------------------
    CREATE OR REPLACE PACKAGE BODY 패키지명
    IS
        저장프로시저와 저장함수 정의
    END;
    /
    
    실행) EXEC[UTE] 패키지명.저장프로시저명
    -------==================================================================================
    ---------------------패키지 선언---------------------
    create or replace package encore
    is
       procedure del_ename(delEname varchar2);
       function call_bonus(vename emp.ename%type) return number;
    end;
    /
    ---------------------패키지 실행(body)---------------------
    create or replace package body encore
    is
        -- 특정사원(이름) 삭제 프로시저
        procedure del_ename(delEname varchar2)
        is
    
        begin    
            delete from emp3
            where ename= delEname;
            commit;
            dbms_output.put_line('#'||delEname||'사원이 삭제되었습니다');
       end; 
    
       -- 특정사원의 보너스 얻는 함수
       function call_bonus(vename emp.ename%type)
          return number
          is
            sal emp.sal%type;
            bonus   number;
          begin
              select sal into sal
              from emp
              where ename = vename;  
              -- 보너스 계산
              bonus := sal*2;
       return bonus;    
       end;   
    end;
    /
    --==> Package body created
    SQL> exec encore.del_ename('FORD');
    #FORD사원이 삭제되었습니다
    
    SQL> variable bonus number;
    SQL> exec :bonus  := encore.call_bonus('KING');
    
    SQL> print bonus
    
         BONUS
    ----------
         10000

<Trigger.> 트리거

  • 이벤트 처리(~했을 때 수반되는 처리)

  • 특정테이블에 이벤트가 발생했을 시 다른 테이블에 연관된 내용을 변경하도록 하는 일.

  • 형식

    CREATE [OR REPLACE] TRIGGER 트리거명
    ( BEFORE | AFTER ) ( INSERT | DELETE | UPDATE ) -- 이벤트(사건발생)
    ON 테이블명 -- 어디에서? ON, 이벤트가 발생하는 테이블
    [FOR EACH ROW] -- 실행될 문장 행에 각각 적용
    [WHEN 조건식]
    BEGIN
        --이벤트 발생시 실행할 문장(주로 DML문장)
    END;
    /
  • 문제

    문제)
    사원테이블(EMP2)에 사원정보가 새로 입력될 때마다(이벤트) 입사 환영메시지(이벤트처리 BEGIN~END)를 출력하시오.
    
    DROP TABLE emp2;
    CREATE TABLE emp2
    AS SELECT empno, ename, deptno
    FROM emp
    WHERE 1=0;
    
    -- 환영 트리거 생성
    CREATE OR REPLACE TRIGGER welcome
    AFTER INSERT ON emp2 --emp2 테이블에서 행입력이 발생했다면! (발생한 후)
    FOR EACH ROW
    BEGIN
        DBMS_OUTPUT.PUT_LINE('ENCORE 주식회사 입사를 환영합니다.');
    END;
    /
    
    --
    INSERT INTO emp2 VALUES (7000, '진주',10);
    --ENCORE 주식회사 입사를 환영합니다.
    INSERT INTO emp2 VALUES (7000, '용진',20);
    --ENCORE 주식회사 입사를 환영합니다.
    INSERT INTO emp2 VALUES (7002, '비키',30);
    --ENCORE 주식회사 입사를 환영합니다.

<바인드변수> - 매개변수, 전달변수, PL/SQL에서는 변수명 앞에 ':'을 붙여서 사용

​ :NEW - 새로 입력 (INSERT, UPDATE) 된 데이터

​ :OLD - 기존 데이터 (이미 저장되어 있는 데이터)

  • BEGIN ~ END 에서 사용법

    : NEW. 컬럼명

    ​ VALUES (데이터)

    ​ SET 컬럼명 = 데이터

    : OLD.컬럼명

    CREATE OR REPLACE TRIGGER welcome
    AFTER INSERT ON emp2
    FOR EACH ROW
    BEGIN
        DBMS_OUTPUT.PUT_LINE('[' || :NEW.ename || '] 님의 ENCORE 주식회사 입사를 축하합니다');
    END;
    /
    
    --
    INSERT INTO emp2 VALUES (7006, '딩딩', 20);
    --[딩딩] 님의 ENCORE 주식회사 입사를 축하합니다
    INSERT INTO emp2 VALUES (7008, '삑삑', 20);
    --[삑삑] 님의 ENCORE 주식회사 입사를 축하합니다
  • 문제

    문제)
    사원테이블(emp3)에 사원정보가 (empno, ename, sal, hiredate)입력외었을 때 급여테이블(salary[no,sal])에 그 사원에 대한 급여 정보가 자동으로 입력되도록 트리거를 생성하시오
    
    DROP TABLE emp3;
    
    CREATE TABLE emp3
    AS SELECT empno, ename, sal, hiredate
    FROM emp
    WHERE 1=0;
    
    CREATE TABLE salary
    (
        no NUMBER,
        sal NUMBER(7,2)
    );
    
    CREATE SEQUENCE salary_seq
    START WITH 1
    INCREMENT BY 1
    NOCYCLE
    NOCACHE;
    
    CREATE OR REPLACE TRIGGER sal_info
    AFTER INSERT ON emp3
    FOR EACH ROW
    BEGIN
        INSERT INTO salary(no, sal) VALUES(salary_seq.nextval, :new.sal);
    END;
    /
    
    --먼저 조회부터
    SELECT * FROM salary;
    
    --emp3테이블 : empno, ename, sal, hiredate
    INSERT INTO emp3 VALUES (8000, '딩딩', 3000, SYSDATE);
    INSERT INTO emp3 VALUES (8001, '용용', 4000, SYSDATE);
    INSERT INTO emp3 VALUES (8002, '빜빜', 5000, SYSDATE);
    
    --
    SELECT * FROM emp3;
    SELECT * FROM salary;
    

<테이블 만들기>

1. 상품테이블
CREATE TABLE 상품
(
    상품코드     CHAR(4) CONSTRAINT 상품_PK PRIMARY KEY,
    상품명      VARCHAR2(15) NOT NULL,
    제조사         VARCHAR2(15),
    소비자가격     NUMBER,
    재고수량     NUMBER DEFAULT 0
);

2. 입고테이블
DROP TABLE 입고;
CREATE TABLE 입고
(
    입고번호     NUMBER CONSTRAINT 입고_PK PRIMARY KEY,
    상품코드     CHAR(4) CONSTRAINT 입고_FK REFERENCES 상품(상품코드),
    입고일자     DATE DEFAULT SYSDATE,
    입고수량     NUMBER,
    입고단가     NUMBER,
    입고금액     NUMBER
);

CREATE SEQUENCE 입고_SEQ
            START WITH 1
            INCREMENT BY 1
            NOCYCLE
            NOCACHE;

<상품테이블에 정보입력>
- 상품코드, 상품명, 제조사, 소비자가격, 재고수량(POINT!)

INSERT INTO 상품 ( 상품코드, 상품명, 제조사, 소비자가격 )
            VALUES ( 'a001', '마우스', '진꼬', 1000);
INSERT INTO 상품 ( 상품코드, 상품명, 제조사, 소비자가격 )
            VALUES ( 'a002', '키보드', '꼬진', 2000);
INSERT INTO 상품 ( 상품코드, 상품명, 제조사, 소비자가격 )
            VALUES ( 'a003', '모니터', '빜빜', 5000);    

상품코드 상품명                         제조사                         소비자가격   재고수량
-------- ------------------------------ ------------------------------ ---------- ----------
a001     마우스                         진꼬                                 1000          0
a002     키보드                         꼬진                                 2000          0
a003     모니터                         빜빜                                 5000          0
--================================================================================================
1. 입력트리거 ( 입고테이블에 상품이 입력 되었을 때 재고수량 증가! )
예) 입고테이블에 키보드가 10개 입고되었을 때 자동으로 삼품테이블의 'a002'상품의 재고가 0 - - > 10으로 변경

CREATE OR REPLACE TRIGGER product_insert
AFTER INSERT ON 입고
FOR EACH ROW
BEGIN
    -- 상품테이블에 대한 [재고수량] 수정
    UPDATE 상품 SET 재고수량 = 재고수량 + :NEW.입고수량 -- 0 + 10
    WHERE 상품코드 = :NEW.상품코드 ; -- 상품코드 = 'a002'
END;
/

SELECT 상품코드, 상품명, 재고수량 FROM 상품;
상품코드 상품명                           재고수량
-------- ------------------------------ ----------
a001     마우스                                  0
a002     키보드                                  0
a003     모니터                                  0

--입고테이블) 입고번호, 상품코드, 입고일자, 입고수량, 입고단가, 입고금액
INSERT INTO 입고 ( 입고번호, 상품코드, 입고수량, 입고단가, 입고금액 )
             VALUES( 입고_seq.nextval, 'a002', 10, 1000, 10000);

--이렇게 두번 넣으면
SELECT * FROM 상품;                                ;

상품코드 상품명                         제조사                         소비자가격   재고수량
-------- ------------------------------ ------------------------------ ---------- ----------
a001     마우스                         진꼬                                 1000          0
a002     키보드                         꼬진                                 2000         20
a003     모니터                         빜빜                                 5000          0


--================================================================================================

2. 수정트리거 (입고테이블에 상품의 입고 수량이 변경되었을 때 상품테이블의 재고수량 변경)
--> product_update
--> 예) 종업원의 실수로 잘못입력된 입고번호 10 ----------->20으로 변경시

해당 상품코드에 대한 (상품테이블) 재고 수량이 40 --> 50으로 변경되어 지는

[입고]테이블의 입고 수량 변경 ----------> [상품] 테이블의 재고 수량 변경

CREATE OR REPLACE TRIGGER product_update
AFTER UPDATE ON 입고
FOR EACH ROW
BEGIN
    -- 상품테이블에 대한 [재고수량] 수정
    UPDATE 상품 SET 재고수량 = 재고수량 -:OLD.입고수량 + :NEW.입고수량
    WHERE 상품코드 = :OLD.상품코드 ; -- 상품코드 = 'a002'
END;
/

---
<상황발생>
update 입고 set 입고수량=30
            where 입고번호=2;

select 입고번호, 상품코드, 입고수량 from 입고;

select 상품코드, 상품명, 재고수량 from 상품;

--================================================================================================

3. 삭제트리거
    ----> 입고번호 2에 대한 삭제!!
          (다른 대리점에 전달되어야 하는 제품이 잘못 배달 되었음)
    ----> [상품]테이블  재고수량 50  ---> 30 변경

    create or replace trigger product_delete
    after delete on 입고   -- 이벤트: 입고테이블에서 삭제 발생시 
    for each row
    begin
      -- 입고 테이블 삭제 발생시  실행할 SQL
      update 상품 set 재고수량= 재고수량        - :old.입고수량
                         -- 50(기존재고) - 20(삭제된입고)  ==> 30      
      where  상품코드 = :old.상품코드;   --'a002'; 
    end;
    /                           

<상황발생>
 delete from 입고 where 입고번호=2;

select 입고번호, 상품코드, 입고수량 from 입고;

select 상품코드, 상품명, 재고수량 from 상품;

< Rollup과 Cube >

ROLLUP

  • GROUP BY절과 같이 사용
  • 그룹지어진 집합 결과에 좀 더 상세한 정보 반환

Cube

  • Cross-Tab에 대한 Summary를 추출하는데 사용
  • Rollup에 의해 나타나는 Item Total과 Column Total값을 나타 낼 수 있다.

결론 : 총계와 소계 구할때

ppt보기

1559635341445155963536308815596353691541559635523445

select *
from BOOK, (select rownum
from BOOK
where rownum < 5);
--96행 나옴
-------------------------------------------
select decode(rn, 2, '합계', 3, publisher||' 소계', publisher) "출판사", sum(price)
from BOOK, (select rownum rn
from BOOK
where rownum < 5)
group by decode(rn,2,'합계',3,publisher||' 소계', publisher);

-------------------------------------------

select decode(rn,2,'합계',3,publisher||' 소계', publisher) "출판사",
decode(rn,1,book_type||' 소계',4, book_type) "종류",
sum(price) "가격"
from BOOK, (select rownum rn
from BOOK
where rownum < 5)
group by decode(rn,2,'합계',3,publisher||' 소계', publisher),
decode(rn,1,book_type||' 소계',4, book_type);

-------------------------------------------
select decode(rn,2,'합계',3,publisher||' 소계', publisher) "출판사",
decode(rn,1,book_type||' 소계',4, book_type) "종류",
decode(rn,4,book_name)"책명",
sum(price) "가격"
from BOOK, (select rownum rn
from BOOK
where rownum < 5)
group by decode(rn,2,'합계',3,publisher||' 소계', publisher),
decode(rn,1,book_type||' 소계',4, book_type),
decode(rn,4,book_name)
order by decode(rn,2,'합계',3,publisher||' 소계', publisher);
-------------------------------------------
select publisher, book_type, book_name, sum(price)
from book
group by rollup(publisher, book_type, book_name);

카티션 곱(car)

oracle 8i부터 소계와 합계를 구해주는 함수 제공!!

  • Rollup : group by 순서에 의한 멀티레벨 소계 및 총계를 구해주는 함수
  • Cube : crosstab 형태의 소계를 계산할 때 사용.
SELECT job, SUM(sal)
FROM emp
GROUP BY ROLLUP(job);

JOB                  SUM(SAL)
------------------ ----------
CLERK                    4150
SALESMAN                 5600
PRESIDENT                5000
MANAGER                  8275
ANALYST                  6000

--====================================================================

select job, SUM(sal)
from emp
group by ROLLUP(job);

JOB                  SUM(SAL)
------------------ ----------
ANALYST                  6000
CLERK                    4150
MANAGER                  8275
PRESIDENT                5000
SALESMAN                 5600
                        29025

<부서별 직책 인원수와 급여합계>

SELECT dname, job, SUM(sal) sal, COUNT(*) 인원수
FROM emp e, dept d
WHERE e.deptno = d.deptno
GROUP by dname,job;

DNAME                        JOB                       SAL     인원수
---------------------------- ------------------ ---------- ----------
SALES                        MANAGER                  2850          1
SALES                        CLERK                     950          1
ACCOUNTING                   MANAGER                  2450          1
ACCOUNTING                   PRESIDENT                5000          1
ACCOUNTING                   CLERK                    1300          1
RESEARCH                     MANAGER                  2975          1
SALES                        SALESMAN                 5600          4
RESEARCH                     ANALYST                  6000          2
RESEARCH                     CLERK                    1900          2
--9행 나옴
--==============================================================================
SELECT dname, job, SUM(sal) sal, COUNT(*) 인원수
FROM emp e, dept d
WHERE e.deptno = d.deptno
GROUP by ROLLUP( dname,job );

DNAME                        JOB                       SAL     인원수
---------------------------- ------------------ ---------- ----------
SALES                        CLERK                     950          1
SALES                        MANAGER                  2850          1
SALES                        SALESMAN                 5600          4
SALES                                                 9400          6
RESEARCH                     CLERK                    1900          2
RESEARCH                     ANALYST                  6000          2
RESEARCH                     MANAGER                  2975          1
RESEARCH                                             10875          5
ACCOUNTING                   CLERK                    1300          1
ACCOUNTING                   MANAGER                  2450          1
ACCOUNTING                   PRESIDENT                5000          1
ACCOUNTING                                            8750          3
                                                     29025         14
--13행이 나옴, 소계 총계가 같이 나온다.
--앞에 있는거 기준으로 소분류되며 소계 총계까지 나온다.
--==============================================================================
--이번에는 job끼리 묶고 싶어 이럴 때 cube~!
--직책 기준의 소계를 알고 싶다~!
SELECT dname, job, SUM(sal) sal, COUNT(*) 인원수
FROM emp e, dept d
WHERE e.deptno = d.deptno
GROUP by ROLLUP( dname,job )
    UNION
SELECT job, SUM(sal) sal, COUNT(*) 사원수 -- 직책 기준의 소계를 알고 싶다!
FROM emp
GROUP BY ROLLUP(job);
--ORA-01789: query block has incorrect number of result columns
--주의사항★ : 두 쿼리문의 칼럼수가 일치해야 하고 자료형도 일치해야 합니다.
SELECT dname, job, SUM(sal) sal, COUNT(*) 인원수
FROM emp e, dept d
WHERE e.deptno = d.deptno
GROUP by ROLLUP( dname,job )
    UNION
SELECT '',job, SUM(sal) sal, COUNT(*) 사원수 -- 직책 기준의 소계를 알고 싶다!, ''빈 문자열이라도 넣어서 수 맞추기
FROM emp
GROUP BY ROLLUP(job);

DNAME                        JOB                       SAL     인원수
---------------------------- ------------------ ---------- ----------
ACCOUNTING                   CLERK                    1300          1
ACCOUNTING                   MANAGER                  2450          1
ACCOUNTING                   PRESIDENT                5000          1
ACCOUNTING                                            8750          3
RESEARCH                     ANALYST                  6000          2
RESEARCH                     CLERK                    1900          2
RESEARCH                     MANAGER                  2975          1
RESEARCH                                             10875          5
SALES                        CLERK                     950          1
SALES                        MANAGER                  2850          1
SALES                        SALESMAN                 5600          4
SALES                                                 9400          6 -- 여기까지는 위와 동일
                             ANALYST                  6000          2 -- 여기서부터 추가, 직책기준으로~!
                             CLERK                    4150          4
                             MANAGER                  8275          3
                             PRESIDENT                5000          1
                             SALESMAN                 5600          4
                                                     29025         14

--근데 CUBE사용하면 더 편해~!
SELECT dname, job, SUM(sal), COUNT(*) 사원수
FROM emp e, dept d
WHERE e.deptno = d.deptno
GROUP BY CUBE( dname, job ); -- danme, job으로 한번 job으로 한번

DNAME                        JOB                  SUM(SAL)     사원수
---------------------------- ------------------ ---------- ----------
                                                     29025         14
                             CLERK                    4150          4
                             ANALYST                  6000          2
                             MANAGER                  8275          3
                             SALESMAN                 5600          4
                             PRESIDENT                5000          1
SALES                                                 9400          6
SALES                        CLERK                     950          1
SALES                        MANAGER                  2850          1
SALES                        SALESMAN                 5600          4
RESEARCH                                             10875          5
RESEARCH                     CLERK                    1900          2
RESEARCH                     ANALYST                  6000          2
RESEARCH                     MANAGER                  2975          1
ACCOUNTING                                            8750          3
ACCOUNTING                   CLERK                    1300          1
ACCOUNTING                   MANAGER                  2450          1
ACCOUNTING                   PRESIDENT                5000          1

18 rows selected.
  •  

<GROUPING'> (컬럼)

  • GROUPING 함수는 ROLLUP, CUBE에 모두 사용할 수 있다.
  • GROUPING 함수는 해당 컬럼의 Row가 GROUP BY에 의해서 산출된 Row인 경우에는 0을 반환하고, ROLLUP이나 CUBE에 의해서 산출된 Row인 경우에는 1을 반환하게 된다.
  • 따라서 해당 Row가 결과집합에 의해 산출된 Data 인지,
  • ROLLUP이나 CUBE에 의해서 산출된 Data 인지를 알 수 있도록 지원하는 함수이다.
GROUPING_ID(컬럼a, 컬럼b[, ...])
-- GROUPING(컬럼a)||GROUPING(컬럼b)의 값을 2진수에서 10진수로 변환한 값이다.
128,64,32,16,8,4,2,1
---------------
00000000 --> 0
00000001 --> 1
00000010 --> 2
00000011 --> 3
00000100 --> 4
00000101 --> 5

SELECT deptno, 
        empno, 
        SUM(sal) s_sal, 
        GROUPING(deptno) grp_dept,
        GROUPING(empno) grp_emp,
        GROUPING_ID(deptno, empno) gid
FROM emp e
GROUP by ROLLUP( deptno , empno );

    DEPTNO      EMPNO      S_SAL   GRP_DEPT    GRP_EMP        GID
---------- ---------- ---------- ---------- ---------- ----------
        10       7782       2450          0          0          0
        10       7839       5000          0          0          0
        10       7934       1300          0          0          0
        10                  8750          0          1          1
        20       7369        800          0          0          0
        20       7566       2975          0          0          0
        20       7788       3000          0          0          0
        20       7876       1100          0          0          0
        20       7902       3000          0          0          0
        20                 10875          0          1          1
        30       7900        950          0          0          0
        30       7499       1600          0          0          0
        30       7521       1250          0          0          0
        30       7654       1250          0          0          0
        30       7698       2850          0          0          0
        30       7844       1500          0          0          0
        30                  9400          0          1          1
                           29025          1          1          3

18 rows selected.

<집합연산자>

  • 합집합 UNION

  • 형식)

    SELECT 문
    UNION
    SELECT 문
  • 합집합 UNION ALL ( UNION + 중복데이터 )

    SELECT문1 결과 -------> [1,2,3,4,5,6]
    SELECT문2 결과 -------> [5,6,7,8,9]
    
    UNION결과 ==> [1,2,3,4,5,6 5,6,7,8,9]를 중복 제거해서 [1,2,3,4,5,6,7,8,9]로!
    
    UNION ALL결과 ==> [1,2,3,4,5,6,5,6,7,8,9]로!
  • 교집합 INTERSECT

    SELECT문1 결과 --> [1,2,3,4,5,6]
    SELECT문2 결과 --> [5,6,7,8,9]
        INTERSECT 결과 --> [5,6]
  • 차집합 MINUS(오라클의 경우), EXCEPT(SQL서버의 경우)

    SELECT문1 결과 --> [1,2,3,4,5,6]
    SELECT문2 결과 --> [5,6,7,8,9]
    
    SELECT문1
        MINUS 또는 EXCEPT
    SELECT문2
    
    결과 --> [1,2,3,4]
궁금상자
- LOOP문
        LOOP 
        [반복 될 수행문] 
        EXIT WHEN [끝낼 조건]; 
        END LOOP; 

    LOOP :   exit문 사용되었을 경우, 
            EXIT WHEN 이 사용되면 WHEN 절에 LOOP를 빠져나가는 조건 제어 가능

- WHILE LOOP
        WHILE [LOOP가 돌아갈 조건] LOOP 
        [반복 될 수행문] 
        END LOOP; 

    WHILE LOOP : FOR문과 비슷
                조건이 True일 경우에만 반복
                WHILE cnt < 100 LOOP ~ ... ~ EXIT WHEN cnd > 100

-  FOR LOOP
        FOR [반복문에서 사용할 변수 (number 형) - DECLARE에서 정의되면 안됨] 
        IN [반복 시작 상수] .. [반복 끝낼 상수] LOOP 
        [반복 될 수행문] 
        END LOOP; 

        --테이블 행수만큼 반복
            FOR  [반복문에서 사용할 변수 - DECLARE에서 정의되면 안됨]
            IN  ( [테이블] ) LOOP 
            [반복 될 수행문] 
            END LOOP; 
            -- 이때 변수는 number 형이아님
            -- 변수를 r이라고 칭하면 r에 SELECT 된 테이블이 다 들어간다고 생각하면됨
            -- 나중에 r.[필드명]으로 사용


출처: https://jyosssss.tistory.com/36 [개미는 뜐뜐]
궁금상자2
- TRIGGER 왜 쓰는거야? 그냥 IF문 쓰거나 명령어 이어 쓰면 안됨?
궁금상자3
- WHERE 1=0;

 

190605_Day40 <JDBC.>

<JDBC.> Java DataBase Connectivity

  • JDBC 관련 클래스 (java.sql 패키지)

    • DriverManger

      • JVM에서 JDBC전체 관리, Driver등록, Connection 연결작업등..

    • Driver

      • 자신들의 DB를 Vendor(Oracle등)에 연결 할 수 있는 Class를 만드는 인터페이스

    • 채시라--------- 밑에 3개가 중요 순차적으로

    • Connection

      • DB와 연결성을 갖는 인터페이스

    • Statement

      • SQL문을 실행하는 인터페이스

    • ResultSet

      • 조회된 결과 데이터를 갖는 인터페이스

JDBC 프로그래밍

  1. 제품군 선택 (Driver loading) : Oracle? SQLite? 뭐쓸래?

  2. 연결 객체 생성 (Connection) : 서로다른 IP(DB마다 할당된) 중 원하는 DB에 연결하고 싶다라고 하는

    • DB서버의 주소가 필요

    • 포트번호 (한 PC안에서 무슨 서비스를 사용할지 정하기 위해)

    • 계정, 비밀번호

  3. 실행 객체 생성 (Statement)

    • Sql문 작성

  4. 결과 객체 생성 (ResultSet)

    • 행 단위 데이터 얻기(뽑기)

    • 열 데이터 얻기(뽑기)

![1559697810645](C:\Users\Playdata\Documents\K\190605_40일차.assets\1559697810645.png)

 

+ Recent posts