event.stopPropagation() 을 이해하기 위해서는 우선 HTML 상에서 사용자 이벤트가 어떻게 전달되는지 이해해야 합니다.

 

웹에서의 클릭이벤트 전파

propagation 의 사전적의미는 전파, 확산입니다. 

사용자가 마우스로 웹페이지 내의 버튼을 클릭했을때 대부분의 사람들은 버튼만 반응했다고 생각하게 됩니다. 하지만 웹페이 내부에서는 

버튼을 감싸고 있는 부모 태그들 또한 클릭 이벤트에 반응하게 됩니다. 이것을 Bubble Up(버블업)이라고 합니다.

 

 

위 슬라이드 우측의 문서구조를 보면 a 태그는 li, ul 의 두개의 부모태그가 있습니다.

사용자가 a 태그를 클릭했을때 클릭이벤트는 a 태그를 감싸고 있는 li, ul 태그로 순차적으로 전달되게 됩니다. 

즉 a 태그의 onclick  -> li 태그의 onclick  -> ul 태그의 onclick 을 실행하게 됩니다.

만약에 ul 태그에 클릭 이벤트가 있을 경우 a 태그를 클릭하는 순간에는 의도하지 않은 ul 태그의 클릭 이벤트가 실행됩니다.

 

예를 들어 설명하면

이웃집에서 이사를 와서 바로 옆집에 살고 있는 철수네 집에 떡을 돌렸다고 칩시다. 철수는 떡을 받고 기쁜 나머지 아버지에게 가져다 줍니다. 철수 왈 "아버지 옆집에서 새로 이사를 왔다고 맛있는 떡을 주고 갔어요~" 철수는 효심이 지극했습니다. 철수 아버지 또한 효심이 지극하여 받자 마자 바로 철수 할아버지에게 떡을 가져다 줍니다. 철수 아버지 왈 "아버님 옆집에서 새로 이사를 왔다고 맛있는 떡을 주고 갔습니다." 이렇게 3부자는 떡을 오손 도손 나눠 먹게됩니다.

그런데 옆집에서 철수에게 떡을 주면서 "이 떡은 꼭 너 혼자만 먹어야 한다" 라고 말하면서 철수에게 떡을 주었다면... 철수는 혼자 먹습니다. 효심보다는 떡에 눈이 멀었던 거죠...

 

이때 혼자만 먹어라는 의미를 stopPropagation 이라고 합니다.

 

즉, stopPropagation 은 부모태그로의 이벤트 전파를 stop 중지하라는 의미입니다.

 

event.preventDefault() 는?

preventDefault 를 이해하기 위해서는 a 태그를 유심히 봐야 합니다. 위 슬라이드에 표시된 a 태그는 내부적으로 href="#" 속성을 가지고 있습니다. href 속성은 웹브라우저에게 a 태그 클릭시 이동하여야할 페이지를 나타냅니다.

예를 들면) 창조적고찰 블로그</a> 처럼 사용합니다.

 

위 a 태그는 click 이벤트 또한 가지고 있기 대문에 a 태그를 클릭했을 때는 두가지 행동을 하게 됩니다.

첫번째 click 이벤트를 실행합니다. 두번째는 브라우저에게 href 에 표시된 곳으로 이동하도록 합니다.

 

href="#" 속성을 넣은 이유는 a 태그에는 click 이벤트가 있으니 click 이벤트만 실행하고 웹브라우저는 이동하지 말아라 하는 의도로 설정한 값입니다. 이렇게 하게 되면 클릭시에는 click 이벤트만 실행되고 웹브라우저가 이동하지는 않게 됩니다. 제가 생각하기에는 좀 꼼수 같기도 합니다.

 

근데 여기서 한가지 주의해야 할 점이 있습니다. href="#" 은 웹브라우저가 다른 곳으로 이동하지는 않지만 스크롤이 있는 곳에서는 페이지 상단으로 이동하게 됩니다. href="#~~~" 으로 사용하는것을 앵커(닻) 라고 하는데 href="#" 은 웹브라우저의 최상단을 가리키는 앵커입니다.

 

글을 작성할때나, 회원가입을 할때 버튼 한번 클릭할때마다 페이지가 쭉 위로 올라가는 경험을 해보신분들은 그 짜증스러움을 익히 아시리라 생각합니다. ㅠㅠ

 

이 브라우저 행동을 막기위해서 사용하는게 preventDefault 입니다.

 

preventDefault 는 a 태그 처럼 클릭 이벤트 외에 별도의 브라우저 행동을 막기 위해 사용됩니다.



출처: https://ismydream.tistory.com/98 [창조적고찰]

'JAVASCRIPT' 카테고리의 다른 글

#스크립트(Script) 언어 뜻  (0) 2020.04.02

1. 파이썬은 스크립트 언어다? 스크립트 언어의 정의


파이썬은 스크립트 언어다? 늘 아, 그렇구나하고 넘어갔던 '스크립트' 언어에 대해 알아보고자 한다.

스크립트 언어는 연극 용어에서 따온 말이다.

연극에서의 '스크립트'는 배우의 대사를 중점으로 배우의 표정, 등장과 퇴장, 무대장치을 중심으로 지시해놓은 내용을 말한다.

아래는 예시를 위해 가져온 스크립트 샘플이다. (심심하면 읽어보시길)

[출처] http://eslab.inha.ac.kr/wcu/xe/?mid=script_sample 4#. 배 난파 며칠이 지나도 멎지 않는 폭풍으로 인하여 배는 항로에서 점점 멀어졌고 그들은 지쳐갔습니다. 바로그때, 한 선원의 목소리가 들려왔습니다. “육지다!! 육지가 보인다! (갑판에서 육지를 가르키는 한 선원과 그 뒤로 그 곳을 보는 사람들) 그러나 육지를 찾았다는 기쁨도 잠시 (!! 배부셔지는소리) 배가 그만 암초에 걸리고 말았습니다.

프로그래밍에서 '스크립트 언어'의 역할을 생각해보면 왜 스크립트라고 했는지 이해가 될 것이다.

프로그래밍의 스크립트 언어는 기존에 이미 존재하는 소프트웨어를 제어하기 위한 용도를 쓰이는 언어이다.

연극에서 스크립트가 극 안의 상황에서 배우가 어떻게 행동할 것인지 지시해놓은 것처럼,

스크립트 언어도 소프트웨어를 어떻게 실행할 지 제어한다.

2. 스크립트 언어를 쓰는 이유


> 참고 : 컴파일러와 인터프리터의 차이

컴파일러를 사용해 실행하면, 기계어로 번역이 된 채로 바로 실행할 수 있다. 하지만, 규모가 큰 프로그램이라면 컴파일에 몇 시간이 걸릴 수 있다. 그렇게 오랜 시간을 들여 컴파일을 했는데, 얼마 안돼 다시 수정을 한다고 하자. 특히 수정을 많이 해야하는 작업이라면, 시간 낭비가 어마어마할 것이다.

반대로, 인터프리터 방식은 소스코드를 직접 바로바로 실행해 디버깅이 편리하다.

스크립트 언어는 인터프리터 방식에 사용하기 위해 나온 것으로, 응용 소프트웨어와 상호작용하며 제어한다.

아래는 자바스크립트 소스코드의 예시다. 자바스크립트를 사용해 웹 브라우저의 실행을 제어할 수 있다.

궁금한 사람은 현재 창에서 개발자도구(F12 또는 우클릭-검사) - console 에서 아래 코드를 입력하면 된다.

window.open('221457352867')

위에서 말했듯이 스크립트 언어의 특징은 새로운 프로그램을 만들기 보다는 '기존'의 프로그램을 제어하기 위해 쓰인다. 웹이 없다면 자바스크립트를 쓰는 의미가 없는 것처럼, 스크립트 언어들은 기존 프로그램을 전제로 사용한다.

파이썬은 프로그램 개발에도 사용되지만, 다른 프로그램 위에서 스크립트 언어로서 사용되기 편리하므로 스크립트 언어라고 부른다.

3. 장단점


<장점>

- 단순하고 쉬운 문법

- 실시간으로 실행

<단점>

- 실행 속도가 느리므로 속도가 중요할 때는 사용을 지양한다.

(백준 알고리즘에서 같은 문제를 C와 Python을 이용해 풀어볼 것. Python이 10초 이상 걸리는 문제를, C는 1초도 안되어 해결한다)

- 아주 정밀한 산술 연산을 해야할 때

 

 

출처 : https://m.blog.naver.com/PostView.nhn?blogId=guseod24&logNo=221463125647&categoryNo=41&proxyReferer=https%3A%2F%2Fwww.google.com%2F

 

[좋은 IT 용어] #스크립트(Script) 언어 뜻

1. 파이썬은 스크립트 언어다? 스크립트 언어의 정의파이썬은 스크립트 언어다? 늘 아, 그렇구나하고 넘어...

blog.naver.com

 

'JAVASCRIPT' 카테고리의 다른 글

event.stopPropagation(), event.preventDefault() 이해하기  (0) 2020.04.22

< JDBC연동할때 설정>
C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib 경로에 있는 ojdbc6.jar파일을 
C:\Program Files\Java\jre1.8.0_231\lib\ext 경로에 넣기
C:\Program Files\Java\jdk1.8.0_231\jre\lib\ext 경로에 넣기

< DB접속을 못했을시 >
제어판 ->관리도구-> 서비스 -> OracleXETNSListener 서비스 실행되었는지 확인해보기

<내컴퓨터 이름변경시>
C:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN폴더의
listener.ora 파일과 tnsnames.ora 파일의 HOST명 바꾸기

 

DB접속못했을시 조치요령1_ojdbc6파일위치(패스안잡고자동으로인식하게하는방법)
DB접속못했을시 조치요령_2ojdbc6파일위치(패스안잡고자동으로인식하게하는방법)
DB접속못했을시 조치요령_3 ojdbc연결 안되는 에러 발생 시 조치방법
DB접속못했을시 조치요령4

 

'DATABASE' 카테고리의 다른 글

오라클 서브쿼리 정리  (0) 2020.03.11
IN,ANY,ALL 차이점  (0) 2020.03.11
오라클 sql 명령어 IN/ANY 구분  (0) 2020.03.09
오라클 실행순서 형식  (0) 2020.02.25

ORACLE_FINAL.xps
0.20MB
JAVA_FINAL.xps
0.32MB
과제.txt
0.01MB

 

퀴즈.txt
0.00MB
jdbc01.zip
0.02MB

 

 

데이터베이스 연동해서 추가,지정,삭제


오라클 연동하기위한 클래스 필요

자바진영 ; CONNECTION 필요 (접속/종료 용도)
오라클진영 ; DBMS

STATEMENT

1.
오라클에서 특정 DB하고 연동하는 클래스 파일들의 묶음-라이브러리를 가져와야함.
C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib

2.
자바(JVM)가 해당 (외부)라이브러리 잡게한다
->클래스패스 지정
변수이름: classpath
변수값: \oraclexe\app\oracle\product\11.2.0\server\jdbc\lib\ojdbc6.java
대신에

**프로젝트 안에서 일시적으로 클래스패스를 걸어준다**(아래방법으로 외부라이브러리 사용)

사용에 필요한 라이브러리 일일히 클래스패스지정 삭제 대신에
해당 라이브러리를 실행할 때만 JVM이 실행하도록 지정 

이클립스실행

자바프로젝트
Build Path -> Configure Build Path ->Libraries 탭-> add external JARs -> ojdbc6.java -> apply and close

DB접속종료/트랜지션처리: CONNECTION
SQL구문실행은 CONNECTION이 아닌 STATEMENT로 이루어진다.
new생성이 아닌 connection이 받아온 것을 사용해야한다.

COMMIT; 명령어 없어도 JDBC는 자동 COMMIT.
executeQuery ;  ResultSet object을 리턴타입 가짐 -> select로부터 받아온 데이터를 접근할 수 있음 ; cursor와 비슷

Resultset-rs는 record의 앞뒤로 시작/끝 영역을 알리는 문자가 존재
맨 첫 번째 위치를 가리킴(맨 첫번 째 문자 바로 이전)
그러므로 rs.next();로 실제 첫 데이터로 위치시켜야함.
rs.next(); 다음행(다음데이터)을 가리킴.

다음행이 있으면 true 없으면 false, 리턴값 boolean형
false가 있으면 데이터가 없다는 뜻이므로. while문 사용 시 false가 나올때 까지 돔.

" " -> 자바에서 필요한 문자열
' '  -> SQL에서 인식하는 문자열

desc members; --> 컬럼속성 보여주는 명령어
        ㄴ테이블명

시험출제내용
<<인덱스,제약조건 특징>> 등 암기 필요

    [5] 커서(Cursor)
      - sql문을 실행할때마다 sql문 처리를 위한 메모리공간을 사용하는데 이를 접근하기
        위해 커서를 사용한다.
      
      - 커서의 단계
        1) 커서 선언하기
        2) 커서 오픈하기 --실제로 메모리에 올라가는 단계
        3) 커서에서 추출한 결과 저장하기
        4) 커서닫기

예1) 커서를 사용해서 모든 사원의 번호, 이름, 급여 출력하기

DECLARE
VEMPNO NUMBER(4);
VENAME VARCHAR2(10);
VSAL NUMBER(7,2);
CURSOR C1 -- 커서 선언하기(C1 커서명-- 임의지정가능)
IS
SELECT EMPNO, ENAME, SAL
FROM EMP
WHERE DEPTNO=10;
BEGIN
OPEN C1; --2) 커서 열기
LOOP
FETCH C1 INTO VEMPNO, VENAME, VSAL; --3)C1에서 데이터꺼내와 변수에 저장하기
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('번호:' || VEMPNO || ' 이름:' || VENAME ' 급여:' || VSAL);
END LOOP;
CLOSE C1; --4) 커서닫기
END;
/
    
     예2) 모든 사원번호,사원이름,급여,급여가3000이상이면 높음,2000이상이면 보통,
          2000미만이면 낮음을 출력하세요.

DECLARE
VEMPNO EMP.EMPNO%TYPE;
VENAME EMP.ENAME%TYPE;
VSAL EMP.SAL%TYPE;
LEVEL VARCHAR2(10); --높음,보통,낮음 단계를 저장할 변수
CURSOR C1
IS
SELECT EMPNO, ENAME, SAL FROM EMP;

BEGIN
OPEN C1; 
LOOP
FETCH C1 INTO VEMPNO, VENAME, VSAL;
EXIT WHEN C1%NOTFOUND;
IF VSAL>=3000 THEN
LEVEL := '높음';
ELSIF VSAL>=2000 THEN
LEVEL := '보통';
ELSE
LEVEL := '낮음';
END IF;
DBMS_OUTPUT.PUT_LINE(VEMPNO|| ' ' ||VENAME|| ' ' ||VSAL|| ' ' ||LEVEL);
END LOOP;
CLOSE C1;
END;
/
   
    Q1) 커서를 사용해서 모든 사원의 이름,급여,전체사원의 급여합을 구해서 출력해 보세요.

DECLARE
VENAME EMP.ENAME%TYPE;
VSAL EMP.SAL%TYPE;
TOTSAL NUMBER(7,2) :=0; -- **초기값 지정해야 결과값 도출됨
CURSOR C1
IS
SELECT ENAME, SAL FROM EMP;

BEGIN
OPEN C1; 
LOOP
FETCH C1 INTO VENAME, VSAL;
EXIT WHEN C1%NOTFOUND;
TOTSAL := TOTSAL + VSAL;
DBMS_OUTPUT.PUT_LINE(VENAME|| ' ' ||VSAL);
END LOOP;
DBMS_OUTPUT.PUT_LINE('전체사원의 급여합: '||TOTSAL); --LOOP가 끝난 다음에 위치
CLOSE C1;
END;
/

      예3) 각 부서의 급여합 구하기
       (PROCEDURE로 만들기)
CREATE OR REPLACE PROCEDURE DEPT_SAL
IS
CURSOR C1
IS
SELECT NVL(SAL,0) SAL,DEPTNO FROM EMP; -- NVL ; NULL 값이 있으면(계산자체가안됨) '0'으로 넣어주는 명령어 / 그 옆에 SAL은 ALIAS
D1 NUMBER(5):=0; --10번부서합
D2 NUMBER(5):=0; --20번부서합
D3 NUMBER(5):=0; --30번부서합
BEGIN
--FOR 문을 사용하면 OPEN과 CLOSE를 하지 않아도 된다.
FOR CURVAL IN C1 LOOP --C1에서 데이터를 꺼내와 CURVAL 변수(SAL/DEPTNO 데이터를 통으로 꺼내와서 저장)에 저장
IF CURVAL.DEPTNO=10 THEN
D1 := D1 + CURVAL.SAL;
ELSIF CURVAL.DEPTNO=20 THEN
D2 := D2 + CURVAL.SAL;
ELSIF CURVAL.DEPTNO=30 THEN
D3 := D3 + CURVAL.SAL;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('10번부서합:' || D1);
DBMS_OUTPUT.PUT_LINE('20번부서합:' || D2);
DBMS_OUTPUT.PUT_LINE('30번부서합:' || D3);
END;
/        

EXECUTE DEPT_SAL;

    Q2) 커서를 사용해서 모든 사원번호,이름,부서명,급여,보너스,부서번호를 출력하는
        프로시져를 만들고 사용해 보세요.
보너스는 부서번호가 10번이면 급여의 10%
         부서번호가 20번이면 급여의 20%
         부서번호가 30번이면 급여의 30%

((* 문제에 <모든> 사원번호가 있으므로 CURSOR 사용. FOR문 이용해여 작성))

CREATE OR REPLACE PROCEDURE PRINTINFO
IS
CURSOR C1
IS
SELECT EMPNO 사원번호, ENAME 이름, DNAME 부서명, SAL 급여, D.DEPTNO 부서번호 FROM EMP E, DEPT D WHERE E.DEPTNO=D.DEPTNO ;
BONUS NUMBER(5):=0;
BEGIN
FOR CURVAL IN C1 LOOP --C1에서 데이터를 꺼내와 CURVAL 변수(SAL/DEPTNO 데이터를 통으로 꺼내와서 저장)에 저장
IF CURVAL.부서번호=10 THEN
BONUS := CURVAL.급여 * 0.1;
ELSIF CURVAL.부서번호=20 THEN
BONUS := CURVAL.급여 * 0.2;
ELSIF CURVAL.부서번호=30 THEN
BONUS := CURVAL.급여 * 0.3;
END IF;
DBMS_OUTPUT.PUT_LINE('사원번호:'||CURVAL.사원번호||'이름:'||CURVAL.이름||'부서명:'||CURVAL.부서명||'급여:'||CURVAL.급여||'보너스:'||BONUS);
END LOOP;

END;
/
EXECUTE PRINTINFO;

    [6] 트리거(Trigger)

      - 데이터베이스가 미리 정해놓은 조건을 만족하거나 어떤 동작이 수행되면 
        자동으로 수행되는 동작.특정 동작에 대한 이벤트로 인해서 실행되는 프로시져 --INSERT, UPDATE, DELETE (데이터베이스에서의 이벤트)
      - 형식)
        CREATE OR REPLACE TRIGGER 트리거이름
TIMING[BEFORE|AFTER] EVENT[INSERT|UPDATE|DELETE] ON 테이블명
[FOR EACH ROW] -행마다 적용할 건지 / 
DECLARE
변수선언;
BEGIN
실행문장;
END;
/
      - 트리거유형
       1) 문장레벨트리거 : DML발생시 한번만 수행. 영향을 받는 행이 없어도 수행된다.
       2) 행레벨트리거 : DML발생시 각 행이 변경될때마다 수행. 
                         FOR EACH ROW 옵션을 설정해서 생성한다.
 :OLD 와 :NEW객체를 사용할 수 있다. --오라클에 의해 생성된 OLD(또는 NEW) 객체를 참조한다는 뜻

OLD는 DELETE(수정, 삭제된 행에 대한 정보를 갖는 객체) 에서만 사용가능, NEW(수정, 추가된 행에 대한 정보를 갖고있음)는 INSERT에서만 사용가능 

UPDATE는 OLD,NEW 둘 다 사용가능.

      - 트리거 삭제
       형식) DROP TRIGGER 트리거명;

===============================================================

     예1) 부서가 추가되었을 때, '부서가 추가되었습니다' 를 출력하는 트리거 생성하기
CREATE OR REPLACE TRIGGER MSG_DEPT
AFTER INSERT ON DEPT
BEGIN
DBMS_OUTPUT.PUT_LINE('부서가 추가 되었습니다.');
END;
/
INSERT INTO DEPT VALUES(11, '부서1', '서울');

===============================================================

     Q1) 사원이 수정될때(UPDATE) 사원정보가 수정되었어요. 라고 출력하는 트리거 만들고
       실행되도록 해보세요.

CREATE OR REPLACE TRIGGER MSG_EMP
AFTER UPDATE ON EMP
BEGIN
DBMS_OUTPUT.PUT_LINE('사원정보가 수정되었습니다.');
END;
/
INSERT INTO EMP(EMPNO, ENAME) VALUES(91, '다슬송');

UPDATE EMP SET ENAME ='송다슬' WHERE ENAME='다슬송';

===============================================================
     예3) 행레벨트리거 --> FOR EACH ROW옵션을 설정해서 트리거 생성
    
#문장레벨트리거 - 영향을 받는 행이 없거나 여러 행이 영향을 받아도 무조건 한 번만 수행됨
CREATE OR REPLACE TRIGGER PRINT_MSG
AFTER DELETE ON DEPT
BEGIN
DBMS_OUTPUT.PUT_LINE('부서가 삭제되었어요');
END;
/

SQL> DELETE FROM DEPT WHERE DEPTNO=12;
부서가 삭제되었어요 -- 삭제된 행이 없어도 무조건 1번 수행됨

1 row deleted.

#행레벨트리거 - FOR EACH ROW 옵션주기 -- 영향을 받은 행의 갯수만큼만 실행됨
CREATE OR REPLACE TRIGGER PRINT_MSG
AFTER DELETE ON DEPT
FOR EACH ROW
BEGIN
-- :OLD 삭제된 부서에 대한 정보를 갖는 객체
DBMS_OUTPUT.PUT_LINE(:OLD.DEPTNO || '부서가 삭제되었어요');
END;
/

SQL> DELETE FROM DEPT WHERE DEPTNO>70;

71부서가 삭제되었어요
72부서가 삭제되었어요
81부서가 삭제되었어요
82부서가 삭제되었어요

4 rows deleted.

CREATE OR REPLACE TRIGGER PRINT_DEPTNO
AFTER INSERT ON DEPT
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE(:NEW.DNAME || '부서가 추가되었습니다.');
END;
/

SQL> INSERT INTO DEPT VALUES(55, '부서55', '제주');
부서55부서가 추가되었습니다.
부서가 추가 되었습니다.

1 row created.


      ## 트리거 수정 : DELETE 이벤트에서는 :OLD 객체를 통해 삭제된 행의정보를 얻어옴
      CREATE OR REPLACE TRIGGER PRINT_MSG
      AFTER DELETE ON DEPT
      FOR EACH ROW
      BEGIN
          DBMS_OUTPUT.PUT_LINE(:OLD.DEPTNO || '부서가 삭제되었어요');
      END;
      /

예) UPDATE
CREATE OR REPLACE TRIGGER UPDATE_DEPTNO
AFTER UPDATE ON DEPT
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE(:OLD.DNAME || '부서의 위치가 ' || :OLD.LOC || ' 에서'||  :NEW.LOC || ' 위치로 변경됨');
END;
/

SQL> UPDATE DEPT SET LOC='신촌' WHERE DEPTNO=40;
OPERATIONS부서의 위치가 BOSTON 에서신촌 위치로 변경됨

1 row updated.

  ============================================================
     Q1) EMP테이블에 사원정보가 추가되면 사원번호 XX님이 입사하셨습니다
     라고 출력되는 트리거 만들고 실행되도록 해보기
     
CREATE OR REPLACE TRIGGER MSG_EMP
AFTER INSERT ON EMP
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('사원번호'|| :NEW.ENAME || ' 님이 입사하셨습니다.');
END;
/
INSERT INTO EMP(EMPNO) VALUES(88);
===============================================================
     Q2) EMP테이블에 사원정보가 삭제되면 사원번호 XX님이 퇴사하셨습니다.
     라고 출력되는 트리거 만들고 실행되도록 해보기


CREATE OR REPLACE TRIGGER MSG_EMP
AFTER DELETE ON EMP
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('사원번호'|| :OLD.EMPNO || ' 님이 퇴사하셨습니다');
END;
/
 DELETE FROM EMP WHERE EMPNO=88;
============================================================
     Q3) EMP테이블에서 사원정보가 수정되면 XXX번 사원의 부서가 XXX부서에서
       XXX 부서로 변경되었습니다. ->부서번호 사용
       라고 출력되는 트리거 만들고 실행되도록 해보기

CREATE OR REPLACE TRIGGER UPDATE_DEPTNO
AFTER UPDATE ON EMP
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE(:OLD.EMPNO || '부서의 위치가 ' || :OLD.DEPTNO || ' 에서'||  :NEW.DEPTNO || ' 위치로 변경됨');
END;
/      
    UPDATE EMP SET DEPTNO=40 WHERE DEPTNO=30;

============================================================
예) 상품테이블(재고수량)
CREATE TABLE ITEM
(
CODE CHAR(6) PRIMARY KEY, --상품코드
NAME VARCHAR(12) NOT NULL, -- 상품명
COMPANY VARCHAR2(12), --제조회사
PRICE NUMBER(8), --가격
CNT NUMBER(6) DEFAULT 0
);

  INSERT INTO ITEM VALUES('A01','냉장고','삼성',2000000,0);
  INSERT INTO ITEM VALUES('A02','컴퓨터','삼성',1000000,0);
  COMMIT;

-- 입고테이블(
CREATE TABLE WAREHOUSE
(
NUM NUMBER(6) PRIMARY KEY,
CODE CHAR(6) REFERENCES ITEM(CODE),
PUTDATE DATE, --입고날짜
PUTCNT NUMBER(6), --입고수량
PUTPRICE NUMBER(6) -- 입고단가
);

-- 입고테이블에 데이터 2개 추가해 보세요.
2)  DELETE FROM WAREHOUSE;
 COMMIT;

1)  INSERT INTO WAREHOUSE VALUES(1,'A01','2020/03/16',5,179000);
 INSERT INTO WAREHOUSE VALUES(2,'A02','2020/03/16',10,780000);
 COMMIT;
============================================================
3)  Q1) 입고테이블에 상품이 입고되면 상품테이블에 재고수량이 증가되도록 TRIGGER를 만들어 보세요. (UPDATE 사용)

INSERT INTO WAREHOUSE VALUES(2, 'A02','2020/03/16',10,780000); 
--> ITEM테이블의 'A01' 제품의 재고수량이 10개 증가되도록

CREATE OR REPLACE TRIGGER U_ITEM -- UPDATE_ITEM은 오류발생 (UPDATE라는 명령어가 존재하기 때문?)
AFTER INSERT ON WAREHOUSE
FOR EACH ROW
BEGIN
UPDATE ITEM SET CNT= (CNT+:NEW.PUTCNT) WHERE CODE= :NEW.CODE; 
DBMS_OUTPUT.PUT_LINE( :NEW.PUTCNT || '만큼 증가되었습니다.'); 
END;
/

(강사답안)
CREATE OR REPLACE TRIGGER INSERT_WAREHOUSE
AFTER INSERT ON WAREHOUSE
FOR EACH ROW
BEGIN
UPDATE ITEM SET CNT=CNT + :NEW.PUTCNT
WHERE CODE=:NEW.CODE;
END;
/
============================================================
Q2) 입고정보 삭제하기
 DELETE FROM WAREHOUSE WHERE NUM=1; -- 상품테이블의 재고수량이

 -- 삭제된 수량만큼 감소되도록(ITEM 테이블에서) 트리거 만들어 보세요.

CREATE OR REPLACE TRIGGER DELETE_WAREHOUSE
AFTER DELETE ON WAREHOUSE
FOR EACH ROW
BEGIN
UPDATE ITEM SET CNT=CNT - :OLD.PUTCNT
WHERE CODE=:OLD.CODE;
END;
/
=============================================================
Q3) 입고수량 수정하기
  UPDATE WAREHOUSE SET PUTCNT=3 WHERE NUM=1;
   -- A01제품의 재고수량이 수정된 수량만큼 변경되도록 트리거 만들기

CREATE OR REPLACE TRIGGER UPDATE_WAREHOUSE
AFTER UPDATE ON WAREHOUSE
FOR EACH ROW
BEGIN
UPDATE ITEM SET CNT = CNT - :OLD.PUTCNT + :NEW.PUTCNT 
WHERE CODE = :OLD.CODE; -- (NEW.CODE도 가능)
END;
/

UPDATE WAREHOUSE SET PUTCNT=3 WHERE NUM=1;
SELECT * FROM ITEM;

COMMIT;

    [7] 예외처리
형식)
EXCEPTION WHEN 예외타입1 THEN 예외처리1
  WHEN 예외타입2 THEN 예외처리2
  ..
  WHEN OTHERS THEN 예외처리3;--위에서 설정된 예외 이외의 예외를 처리

       예1)
        DECLARE
NUM1 NUMBER(5);
NUM2 NUMBER(5);
NUM3 NUMBER(5);
BEGIN
NUM1 := &NUM1;
NUM2 := &NUM2;
NUM3 := NUM1/NUM2;
DBMS_OUTPUT.PUT_LINE(NUM1 || '/' || NUM2 ||'=' || NUM3);
EXCEPTION WHEN ZERO_DIVIDE THEN DBMS_OUTPUT.PUT.LINE('0으로 나눌 수 없음');
  WHEN OTHERS THEN DBMS_OUTPUT.PUT.LINE('오류발생');
END;
/

-- 급여에 대한 정보를 갖는 테이블
CREATE TABLE PAY
(
NUM NUMBER(5) PRIMARY KEY, --PK주기위한 의미없는 번호
EMPNO NUMBER(5) REFERENCES EMP(EMPNO),
PASL NUMBER(10), -- 급여정보
D DATE -- 지급일
);
CREATE SEQUENCE PAY_SEQ;

INSERT INTO PAY VALUES(PAY_SEQ.NEXTVAL,7369,3000,2020/2/28');
--> 급여가 지급될 사원번호와 급여, 지급일을 파라미터로 전달받아
PAY테이블에 정보가 추가되고 EMP테이블에 급여정보가 수정디는 프로시져를
만들고 호출해 보세요.

EXECUTE EMP_PAY(7369,4000000000000000000000000000000000000,'2020/2/28' );

CREATE OR REPLACE PROCEDURE EMP_PAY
(
VEMPNO EMP.EMPNO%TYPE,
VSAL EMP.SAL%TYPE,
VDATE PAY.D%TYPE
)
IS
BEGIN
INSERT INTO PAY VALUES(PAY_SEQ.NEXTVAL,VEMPNO,VSAL,VDATE);
UPDATE EMP SET SAL=VSAL WHERE EMPNO=VEMPNO;
COMMIT;
EXCEPTION WHEN OTHERS THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE('오류로 인해 작업을 모두 취소했습니다.');
END;
/

송다슬_과제.txt
0.00MB
오라클_7.txt
0.02MB
0316과제.zip
0.00MB
2020-03-16 MEMO.txt
0.00MB

 

오라클_5.txt
0.02MB
오라클_6(plsql).txt
0.01MB

 

 <10> TCL (Transaction Control Language)
     (1) 트랜젝션 : 분리되어서는 안되는 논리적 작업 단위
(ex: 여행사상품예약프로그램<숙소테이블/렌트카/항공권/결제 등등>/계좌이체프로그램<입/출금 테이블>)
(cf:스프링; 트랜젝션 처리가 쉬움)

     (2) TCL : DML(UPDATE, DELETE, INSERT)문이 실행되어 DBMS에 저장되거나 되돌리기 위해 실행해야 하는 SQL
     (3) TCL 의 종류
1) COMMIT : SQL구문의 결과를 영구적으로 DB에 반영
2) ROLLBACK : SQL구문의 결과를 취소
3) SAVEPOINT : 트랜젝션의 한 지점에 표시하는 임시 저장점
     (4) TCL 의 특성
읽기일관성/잠금현상 : 어떤 사용자가 변경중인 행을 다른 사용자가 변경할 수 없게 하는 기술로써 변경중인 사용자에 의해 COMMIT 또는 ROLLBACK이 실행된 후 변경되는 특성
     (5) 트랜젝션의 시작과 종료
1) DBMS에 처음 접속했을 때
2) COMMIT 또는 ROLLBACK했을 때
3) DDL구문(CREATE,DROP,..)이 실행되었을 때
   ㄴCOMMIT 되지 않은 이전 DML명령어들이 자동으로 COMMIT된다.

예1)
 # DB접속 - 트랜잭션 시작
SQL> INSERT INTO DEPT VALUES(51,'부서1','서울');
SQL> INSERT INTO DEPT VALUES(52,'부서2','종로');
SQL> INSERT INTO DEPT VALUES(53,'부서3','종로');

SQL> COMMIT; -- 트랜잭션종료/새로운 트랜잭션 시작(51,52,53번부서 추가)

SQL> INSERT INTO DEPT VALUES(61,'부서4','종로');
SQL> INSERT INTO DEPT VALUES(62,'부서5','종로');

SQL> ROLLBACK; -- 트랜잭션종료/새로운 트랜잭션 시작(61,62번부서 취소)

SQL> INSERT INTO DEPT VALUES(71,'부서4','종로');
SQL> INSERT INTO DEPT VALUES(72,'부서4','송파');

SQL> CREATE TABLE AA(A NUMBER(5)); -- 트랜잭션종료/새로운 트랜잭션 시작(71, 72번 부서추가)

*INSERT 후 COMMIT 하지 않고 EXIT로 종료할 시에 해당부분 자동으로 COMMIT되고 프로
그램 종료.

    DEPTNO DNAME                        LOC
---------- ---------------------------- ---------
        10 ACCOUNTING                NEW YORK
        20 RESEARCH                     DALLAS
        30 SALES                           CHICAGO
        40 OPERATIONS                  BOSTON
        51 부서1                          서울
        71 부서4                          종로
        52 부서2                          종로
        53 부서3                          종로
        72 부서4                          송파


예2)
SQL> INSERT INTO DEPT VALUES(81,'부서81','송파');
SQL> INSERT INTO DEPT VALUES(82,'부서82','송파');

SQL> SAVEPOINT A; -- SAVEPOINT 설정
Savepoint created.

SQL> INSERT INTO DEPT VALUES(83,'부서83','송파');
SQL> INSERT INTO DEPT VALUES(84,'부서84','송파');
SQL> ROLLBACK TO A; --A 지점이후부터 ROLLBACK됨(83,84번 작업취소)
Rollback complete.

SQL> SELECT * FROM DEPT;

    DEPTNO DNAME                        LOC
---------- ---------------------------- -----------
        10 ACCOUNTING                   NEW YORK
        20 RESEARCH                     DALLAS
        30 SALES                        CHICAGO
        40 OPERATIONS                   BOSTON
        51 부서1                        서울
        71 부서4                        종로
        53 부서3                        종로
        72 부서4                        송파
        81 부서81                       송파
        82 부서82                       송파

   (11) 시퀀스(ex: 게시판에서 글 번호 순차적으로 정렬되어야 할 때, 수식이 아닌 시퀀스 사용)
     - 연속되는 숫자값을 자동으로 증감시키는 일련번호를 발생시키는 객체
     - 형식
       CREATE SEQUENCE 시퀀스명
       [INCREMENT BY N] 
       [START WITH N] --  이미 시퀀스 생성된 이후 특정 번호부터 다시 발생시켜야할 때 사용
       [MAXVALUE N | NONMAXVALUE N]
       [MINVALUE N | NONMINVALUE N]
       [CYCLE | NOCYCLE ] --최대 또는 최소 값에 도달했을 때 반복할지 정함
       [CACHE | NOCACHE ] --미리 한 번에 만들어서 하나씩 꺼냄(하나 씩 만들어서 하나씩 꺼낼 때 보다 성능 빠름)_시퀀스 성능이 다소느리므로 CACHE를 많이 사용. (NOCACHE 성능 많이 떨어짐)-성능향상관련개념-->튜닝. **화면단으로 순차적으로 보이게 로직으로 만들고, 데이터베이스로는 PK로 중복값이 없고 최신글이 앞으로 나오게 잡아준다. (즉 1->2->3->4->7->9 이러한 문제는 중요치 않음)

     - 삭제
       DROP SEQUENCE 시퀀스명;
     - 함수
       NEXTVAL : 다음값 얻어오기
       CURRVAL : 현재발생된 값 얻어오기

     예1)
     CREATE SEQUENCE MYSEQ;
     SELECT MYSEQ.NEXTVAL FROM DUAL; --'DUAL'은 테이블이 없을 때 임시사용됨

    SQL> SELECT MYSEQ.NEXTVAL FROM DUAL;

   NEXTVAL
----------
         1
SQL> SELECT MYSEQ.NEXTVAL FROM DUAL;

   NEXTVAL
----------
         2
SQL> SELECT MYSEQ.NEXTVAL FROM DUAL;

   NEXTVAL
----------
         3

SQL> DROP SEQUENCE MYSEQ;

Sequence dropped.

SQL> SELECT MYSEQ.NEXTVAL FROM DUAL;
SELECT MYSEQ.NEXTVAL FROM DUAL
       *
ERROR at line 1:
ORA-02289: sequence does not exist

     예2)
      CREATE SEQUENCE MYSEQ1
      INCREMENT BY 10 --10씩 증가
      START WITH 10; --시작값을 10으로 지정
Sequence created.
      SELECT MYSEQ1.NEXTVAL FROM DUAL;

SQL> SELECT MYSEQ1.NEXTVAL FROM DUAL;

   NEXTVAL
----------
        10

SQL> SELECT MYSEQ1.NEXTVAL FROM DUAL;

   NEXTVAL
----------
        20

SQL> SELECT MYSEQ1.CURRVAL FROM DUAL; --현재 발생된 SEQUENCE 값 꺼내오기

   CURRVAL
----------
        20

     예3)
      CREATE TABLE BOARD
      (
NUM NUMBER(5) PRIMARY KEY, --글번호
TITLE VARCHAR2(20),
WRITER VARCHAR2(20),
CONTENT VARCHAR2(50),
REGDATE DATE
     );

     CREATE SEQUENCE BOARD_SEQ; --시퀀스 생성

     INSERT INTO BOARD VALUES(BOARD_SEQ.NEXTVAL, 'TEST1', '김씨','테스트1',SYSDATE);
     INSERT INTO BOARD VALUES(BOARD_SEQ.NEXTVAL, 'TEST2', '이씨','테스트2',SYSDATE);

     COMMIT;

    (11) 뷰(View)
      - 뷰는 테이블에 대한 가상테이블로써 select로 조회된 데이터들의 가상테이블이다.

**명령어 사용(Select 등등) 위해 권한이 필요하다
VIEW 생성을 위해 시스템계정으로 접속하여 권한을 부여해야한다.(scott/tiger 계정에서는 권한이 없으므로 view생성못함)**

      1) 형식
CREATE [OR REPLACE] VIEW 뷰이름 -- VIEW가 없으면 생성하고 있으면 수정하라는 명령어.
AS
서브쿼리;
[ WITH CHECK OPTION ] --; [ ]선택사항
[ WITH READ ONLY ]

기존에 있는 VIEW를 수정할 때는 REPLACE

      2) 사용이유
        - 보안 설정
- 복잡하고 자주 사용되는 질의를 뷰를 통해서 쉽게 사용하기 위해
(=권한 부여를 통해 차등적으로 칼럼을 보여줄 수 있는 기능, ex; SAL칼럼을 빼고 나머지 정보만 보여줌)

예1)
 CREATE VIEW MYEMP1
 AS
  SELECT EMPNO, ENAME,SAL,DEPTNO, FROM EMP;

#VIEW 생성을 위한 권한 부여하기
SQL> conn system/java1234
SQL> GRANT CREATE VIEW TO scott;
Grant succeeded.

CREATE VIEW MYEMP2
AS
 SELECT EMPNO "사원번호",ENAME "이름", SAL "급여", DEPTNO "부서번호"
 FROM EMP;

예2) #DML(INSERT, UPDATE, DELETE) 작업하기
 INSERT INTO MYEMP1 VALUES(8000,'이씨',3000,20); -- 원본테이블(EMP)에도 적용됨
 COMMIT;

예) READ ONLY 옵션 설정하기 - INSERT, UPDATE, DELETE는 못하고 읽기(SELECT)만 가능
CREATE OR REPLACE VIEW MYEMP1
AS
SELECT EMPNO,ENAME,SAL,DEPTNO FROM EMP
WITH READ ONLY;

SQL> INSERT INTO MYEMP1 VALUES(8001, '김씨', 2000, 20);
ㄴERROR at line 1:
   ORA-42399: cannot perform a DML operation on a read-only view

예4) WITH CHECK OPTION - 뷰의 조건에 맞는 데이터들만 DML작업을 할 수 있음
CREATE OR REPLACE VIEW MYEMP1
AS
SELECT EMPNO, ENAME, SAL, DEPTNO FROM EMP
WHERE DEPTNO=10
WITH CHECK OPTION;

SQL> INSERT INTO MYEMP1 VALUES(8002,'김씨',2000,20);
INSERT INTO MYEMP1 VALUES(8002,'김씨',2000,20)
               *
ERROR at line 1:
ORA-01402: view WITH CHECK OPTION where-clause violation
==> 20번 부서는 VIEW의 조건에 맞지 않으므로 오류!

    3) 뷰의 종류
       <1> 단일뷰 : 하나의 테이블로 생성되는 뷰(기본적으로 DML작업이 됨)
       <2> 복합뷰 : 두 개이상의 테이블로 생성되는 뷰(조인된 뷰).DML작업을 못함

예) # 복합뷰만들기
CREATE VIEW MYEMP3
AS
SELECT EMPNO,ENAME,JOB,E.DEPTNO,DNAME
FROM EMP E, DEPT D
WHERE E.DEPTNO=D.DEPTNO;

SQL> SELECT VIEW_NAME FROM USER_VIEWS;

VIEW_NAME
-------------------------
MYEMP1
MYEMP2
MYEMP3

객체들의 정보를 갖고 있는 테이블 같은 저장공간 --> DATA DICTIONARY
SET LINESIZE 100
DESC USER_VIEWS;
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ----------------------------
 VIEW_NAME                                             NOT NULL VARCHAR2(30)
 TEXT_LENGTH                                                    NUMBER
 TEXT                                                           LONG
 TYPE_TEXT_LENGTH                                               NUMBER
 TYPE_TEXT                                                      VARCHAR2(4000)
 OID_TEXT_LENGTH                                                NUMBER
 OID_TEXT                                                       VARCHAR2(4000)
 VIEW_TYPE_OWNER                                                VARCHAR2(30)
 VIEW_TYPE                                                      VARCHAR2(30)
 SUPERVIEW_NAME                                                 VARCHAR2(30)
 EDITIONING_VIEW                                                VARCHAR2(1)
 READ_ONLY                                                      VARCHAR2(1)

    4) 뷰 삭제하기
       형식)
       DROP VIEW 뷰이름;
   
  예)
SQL> DROP VIEW MYEMP1; -- VIEW 삭제하기
View dropped.
SQL> SELECT VIEW_NAME FROM USER_VIEWS;
VIEW_NAME
-----------
MYEMP2
MYEMP3

       Q1) EMP테이블과 DEPT테이블을 이용해서 이름,직업,부서,부서명을 조회하는
        뷰를 만들고 사용해 보세요.
사용후 뷰 삭제하기

CREATE VIEW MYEMP0
AS
SELECT E.ENAME "이름", E.JOB "직업", D.DEPTNO "부서",D.DNAME "부서명"
FROM EMP E, DEPT D
WHERE E.DEPTNO= D.DEPTNO ;

SQL> DROP VIEW MYEMP0;

View dropped.

SQL> SELECT * FROM MYEMP0;
SELECT * FROM MYEMP0
              *
ERROR at line 1:
ORA-00942: table or view does not exist

**VIEW는 DML작업이 아닌 조회를 위한 목적으로 사용됨**

=================================================================
  [12] 인덱스
       - 인덱스란 포인터(주소값을 갖고있는 것)를 사용하여 행의 검색을 촉진시키는 객체
       - 데이터를 빠르게 찾기 위한 이진의 균형탐색 TREE를 이용하여 디스크 입출력횟수를
       줄인다.
       - 인덱스는 논리적으로도 물리적으로도 테이블과 독립적이다.
       - 언제든지 생성하거나 삭제할 수 있으며 이는 테이블과 다른 인덱스에 영향을 
       주지 않는다는 의미이다.
       - 인덱스테이블에는 인덱스키와 ROWID(실제적으로 물리적인 위치)에 대한 정보만을 갖고 있다.
       - 테이블정의의 PRIMARY KEY나 UNIQUE제약조건을 정의할때 UNIQUE인덱스가 자동으로
       생성된다.
       - 형식)
         CREATE [UNIQUE] INDEX 인덱스명 ON 테이블명(컬럼명 ASC|DESC)

예)
 CREATE INDEX IDX_EMP ON EMP(EMPNO DESC);

QL> DESC USER_INDEXES; --사용자가 만든 INDEX에 대한 정보를 갖는 DATA DICTIONARY

 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ---------------------
 INDEX_NAME                                            NOT NULL VARCHAR2(30)
 INDEX_TYPE                                                     VARCHAR2(27)
 TABLE_OWNER                                           NOT NULL VARCHAR2(30)
 TABLE_NAME                                            NOT NULL VARCHAR2(30)
 TABLE_TYPE                                                     VARCHAR2(11)
 UNIQUENESS                                                     VARCHAR2(9)
 COMPRESSION                                                    VARCHAR2(8)
 PREFIX_LENGTH                                                  NUMBER
 TABLESPACE_NAME                                                VARCHAR2(30)
 INI_TRANS                                                      NUMBER
 MAX_TRANS                                                      NUMBER
 INITIAL_EXTENT                                                 NUMBER
... ...

SQL> SELECT INDEX_NAME,TABLE_NAME FROM USER_INDEXES;

INDEX_NAME
-----------------------------------------------------------
TABLE_NAME
-----------------------------------------------------------
SYS_C007004
USERS

SYS_C007005
PURCHASE

PK_STUDENT
MYSTUDENT

INDEX_NAME
-----------------------------------------------------------
TABLE_NAME
-----------------------------------------------------------
PK_EMP
EMP

IDX_EMP **--방금 위에 예제에서 만든 INDEX**
EMP

SYS_C007007
DEPT1


INDEX_NAME
-----------------------------------------------------------
TABLE_NAME
-----------------------------------------------------------
PK_DEPT
DEPT

SYS_C007014
BOARD
ERROR at line 1:
ORA-01418: specified index does not exist

       - 삭제
         DROP INDEX 인덱스명;
DROP INDEX IDX_EMP_EMPNO;


       예1) UNIQUE인덱스 : 인덱스로 설정되는 컬럼에 중복값이 들어가면 안됨  
       CREATE UNIQUE INDEX IDEX_EMP_EMPNO ON EMP(EMPNO DESC);

       예2) 
사원이름 컬럼을 인덱스로 생성해 보세요.

CREATE INDEX IDX_EMP_ENAME ON EMP(ENAME DESC);
Index created.

  SELECT INDEX_NAME,TABLE_NAME FROM USER_INDEXES WHERE INDEX_NAME='IDX_EMP_ENAME';
또는 (위, 아래 결과 같음)
 SELECT INDEX_NAME,TABLE_NAME FROM USER_INDEXES WHERE INDEX_NAME LIKE 'IDX_%';

INDEX_NAME
------------------------------------------------------------
TABLE_NAME
------------------------------------------------------------
IDX_EMP_ENAME
EMP

  
      - 인덱스 생성 기준
       1) 사용자의 SQL에서 WHERE절에 자주 사용되는 컬럼이 대상이 된다.
       2) 인덱스 갯수는 사용형태에 따라 적절하게 생성한다.
       3) 너무 많은 인덱스는 오히려 성능이 감소된다.
       4) 빈번하게 변경되지 않는 테이블에 적용해야 한다.
       5) 작은 테이블보다는 큰 테이블에 인덱스를 생성한다.

      - 인덱스 생성시 주의사항
      DML명령어에 주의해야 한다.
      INSERT -> 테이블에 데이터가 추가되고 인덱스 테이블에 정렬되어 추가된다.
      DELETE -> 삭제시 인덱스 테이블에는 삭제되지 않고 삭제되었음을 표시한다.
               즉 데이터가 남아있게 되므로 실제데이터가 10만건이라면 인덱스에
       데이터는 20만건이 될수도 있다(성능저하) *--오라클은 먼저 인덱스 테이블을 체크하므로
      UPDATE -> 수정시 인덱스테이블에 DELETE된후 INSERT 작업이 수행된다.

   [13] 사용자계정관리

     1) 계정생성
      CREATE USER 아이디 IDENTIFIED BY 비밀번호;
      예)
SQL> CONN system/java1234 -- 계정생성위해 관리자계정으로 접속
SQL> CREATE USER hello1234 IDENTIFIED BY hello0000; --사용자계정만들기
SQL> GRANT connect,resource TO hello1234;-- 접속권한부여하기 (resource; roll 권한부여)
SQL> conn hello1234/hello0000;--사용자계정으로 접속
SQL> CREATE TABLE MYEMP(EMPNO NUMBER(4) PRIMARY KEY,ENAME VARCHAR2(100));

     2) 계정삭제 (*테이블을 객체라고 부름)
       DROP USER 아이디;
       # CASCADE : 삭제할 계정에 데이터가 존재하면 삭제가 안됨. 이때 CASCADE옵션을
주면 삭제 가능

SQL> DROP USER hello1234 CASCADE;

User dropped.

 

======================================================================

 

[2] PL/SQL

    - 구조적인 SQL언어와 달리 SQL를 절차적인 방식에 의해 사용하도록 설계한 언어.
    - PL/SQL의 단위는 블록이며 하나의 블록은 아래와 같은 세부분으로 나뉜다.

    (1) 선언부 : 변수나 상수를 선언하는 부분 
    (2) 실행부 : 실제 처리할 로직을 담당하는 부분
    (3) 예외처리부 : 실행부에서 처리하던 중 발생하는 각종 오류에 대한 처리 부분

    1) PL/SQL의 구조
       DECLARE            -- 선언부
        변수선언
       BEGIN              -- 실행부
        실행구문
       EXCEPTION          -- 예외처리
예외처리구문
       END;
       /  -- PL/SQL실행

       예1) 
        SET SERVEROUTPUT ON -- 출력모드 설정

DECLARE
I_MSG VARCHAR2(20); -- 변수선언
BEGIN
I_MSG :='반가워요';
DBMS_OUTPUT.PUT_LINE('메시지:' || I_MSG);
END;
/
PL/SQL procedure successfully completed.

       예2)
DECLARE
NUM1 NUMBER(5);
NUM2 NUMBER(5);
NUM3 NUMBER(5);
BEGIN
NUM1 := &NUM1; --'&' NUM1 입력받기
NUM2 := &NUM2;
NUM3 := NUM1 + NUM2;
DBMS_OUTPUT.PUT_LINE(NUM1 || '+' || NUM2 || '=' || NUM3);
END;
/

       2) IF ~ ELSE 문
        형식1)
IF 조건식 THEN
  실행문;
ELSE
  실행문;
END IF;

예1) 임의의 정수 입력받아 짝수/홀수 판별하기
DECLARE 
NUM NUMBER(5):=&NUM;
BEGIN
IF NUM MOD 2=0 THEN --MOD 나머지 값 구하는 연산자
DBMS_OUTPUT.PUT_LINE(NUM ||'은 짝수');
ELSE
DBMS_OUTPUT.PUT_LINE(NUM ||'은 홀수');
END IF;
END;
/

형식2)
IF 조건식 THEN
  실행문;
ELSIF 조건식 THEN
  실행문;
ELSIF 조건식 THEN
  실행문;
  ..
END IF;

      

       Q1) 두 정수를 입력받아 두 수중 큰 수 구하기

DECLARE
NUM1 NUMBER(5):=&NUM;
NUM2 NUMBER(5):=&NUM;
BEGIN
IF NUM1>NUM2 THEN
DBMS_OUTPUT.PUT_LINE(NUM1 ||'이 큰수');
ELSE
DBMS_OUTPUT.PUT_LINE(NUM2 ||'이 큰수');
END IF;
END;
/
     Enter value for num: 2
old   2:                NUM1 NUMBER(5):=&NUM;
new   2:                NUM1 NUMBER(5):=2;
Enter value for num: 9
old   3:                NUM2 NUMBER(5):=&NUM;
new   3:                NUM2 NUMBER(5):=9;
9이 큰수

PL/SQL procedure successfully completed.

       Q2) 두 점수를 입력받아 평균이 80이상이면 '합격' 아니면 '불합격' 출력하기

DECLARE
NUM1 NUMBER(5):=&NUM;
NUM2 NUMBER(5):=&NUM;
BEGIN
IF (NUM1 + NUM2)/2 >=80 THEN
DBMS_OUTPUT.PUT_LINE('합격');
ELSE
DBMS_OUTPUT.PUT_LINE('불합격');
END IF;
END;
/
    
      3) FOR문
        
-형식
FOR 변수 IN 초기값..마지막값 LOOP
반복수행할 문장;

END LOOP;

예) 1부터 100까지 합 출력 하시오.

DECLARE
TOT NUMBER(5):=0;
BEGIN
FOR I IN 1..100 LOOP
TOT := TOT + I;
DBMS_OUTPUT.PUT(I || ' '); --1~100까지 옆으로 출력(자바의 PRINT 동일) , PUT_LINE 은 자바의 PRINTLN
END LOOP;
DBMS_OUTPUT.PUT_LINE('1부터 100까지합:' || TOT);
END;
/


        Q1) 1부터 100까지 수 중 3의 배수출력하고 3의 배수합 구해서 출력하기
IF NUM MOD 2=0 THEN --MOD 나머지 값 구하는 연산자

DECLARE
MULTIPLETHREE NUMBER(5):=0;
BEGIN
FOR I IN 1..100 LOOP
IF I MOD 3=0 THEN
MULTIPLETHREE := MULTIPLETHREE + I;
DBMS_OUTPUT.PUT(I || ' ' );
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('1부터 100까지 수 중 3의 배수 합:' || MULTIPLETHREE);
END;
/
3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84
87 90 93 96 99 1부터 100까지 수 중 3의 배수 합:1683

PL/SQL procedure successfully completed.

Q2) 단 입력받아 구구단 출력하기
DECLARE
NUM NUMBER(5) := &NUM;
BEGIN
FOR I IN 1..9 LOOP
DBMS_OUTPUT.PUT_LINE(NUM || '*' || I || '=' || NUM*I);
END LOOP;
END;
/


Q3) 구구단 출력하기(2단부터 9단까지)

2단 2*1=2 2*2=4 ........   2*9=18
        3단 3*1=3 ..

..
9단 9*1=9 9*2=18 .......   9*9=81

FOR I IN 2..9 LOOP
FOR J IN 1..9 LOOP
BEGIN
FOR I IN 2..9 LOOP
DBMS_OUTPUT.PUT(I || '단');
FOR J IN 1..9 LOOP
DBMS_OUTPUT.PUT(I || '*' || J || '=' || I*J || '  ');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' '); --flush와 같음 (데이터 뽑아오는 기능)
END LOOP;
END;
/

       - EXIT : FOR문을 강제로 빠져나가기
        
       예2) 정수입력받아 소수 판별하기

DECLARE
NUM NUMBER(5) := &NUM;
BEGIN
FOR I IN 2..NUM LOOP
IF I=NUM THEN
DBMS_OUTPUT.PUT_LINE(NUM || '는/은 소수 입니다');
ELSIF NUM MOD I = 0 THEN
DBMS_OUTPUT.PUT_LINE(NUM || '는/은 소수가 아닙니다');
EXIT;
END IF;
DBMS_OUTPUT.PUT_LINE(' ');
END LOOP; 
END;
/
Enter value for num: 7
old   2:                NUM NUMBER(5) := &NUM;
new   2:                NUM NUMBER(5) := 7;
7는/은 소수 입니다

PL/SQL procedure successfully completed.

방법1)
FOR문 안에
IF I = NUM
실수입니다.
ELSE IF NUM MOD I = 0
소수입니다.
EXIT

방법2)
NUM-1
IF NUM MOD I = 0
소수입니다.
EXIT
ELSIF I = NUM-1
실수입니다.

https://data-make.tistory.com/25

 

[SQL] 서브쿼리의 모든 것 - Sub Query, Inline View, Scalar, Multi Column

쿼리 안에 또 다른 쿼리 - Sub Query SELECT col1, (SELECT ...) -- 스칼라 서브쿼리(Scalar Sub Query): 하나의 컬럼처럼 사용 (표현 용도) FROM (SELECT ...) -- 인라인 뷰(Inline View): 하나의 테이블처럼 사..

data-make.tistory.com

 

'DATABASE' 카테고리의 다른 글

오라클-자바 연동 시 DB접속 오류 해결 방법  (0) 2020.03.18
IN,ANY,ALL 차이점  (0) 2020.03.11
오라클 sql 명령어 IN/ANY 구분  (0) 2020.03.09
오라클 실행순서 형식  (0) 2020.02.25

03.18 시험출제확정내용=============================================== 
<8> 제약조건<***>
        - 테이블의 해당 컬럼에 잘못된 값이 입력/변경/삭제되는 것을 방지하기 위해
  설정되는 조건(무결성 제약조건)
- 결함이 없는 데이터를 관리하기 위함

       1) 종류
          (1) PRIMARY KEY (기본키)
   - 하나의 테이블에 하나만 존재하며 각 행을 식별하기 위한 용도로 사용
   - NULL값을 허용하지 않고 중복값을 허용안함(NOT NULL + UNIQUE KEY)
         (2) FOREIGN KEY (외래키,참조키)
   - 부모테이블의 특정 컬럼(기본키)를 참조하는 컬럼
   - 부모테이블에 참조하는 값이 없으면 오류가 발생한다.

 

DDL구문(CREATE, DROP, ALTER, ...)
DML구문(ADD, DELETE, UPDATE, SELECT)

 

퀴즈1(2020_03_11).txt
0.00MB
퀴즈1.zip
0.03MB
퀴즈2(2020_03_11).txt
0.00MB
퀴즈2.zip
0.01MB
메모_20200311.txt
0.00MB
오라클_5.txt
0.01MB

 <7> 테이블생성
        - DDL구문 ( CREATE,DROP,ALTER,..)
       1) 형식
CREATE TABLE 테이블명
(
컬럼명 데이터형,
컬럼명 데이터형,
...
);
       2) 기본자료형
        - NUMBER : 숫자(정수,실수)
예)
 NUM NUMBER(5) --> 정수:5자리
 AVER NUMBER(6,2) --> 실수:전체 6자리,소수점이하 2자리 

- CHAR : 고정길이 문자열
  예) JUMIN CHAR(13)  //남는 공간에 빈 문자 생김

- VARCHAR2 : 가변길이 문자열(4000 Bytes) --자바에서는 문자열이 짧으면 VARCHAR2 주로사

  예) ADDR VARCHAR2(100) //

- DATE : 날짜,시간
  예) HIREDATE DATE

- TIMESTAMP : 날짜,시간(시/분/초/밀리초) 예; 경매시스템에 사용(초단위로 결과차이 나므로)
- LONG : 가변길이 문자열(2G Bytes) --자바와 호환이 잘 안됨
- RAW : 가변길이 바이너리 데이터(2000 bytes)
- LONG RAW : 가변길이 바이너리 데이터(2G Bytes)
- BLOB : 바이너리 데이터(4G Bytes)
- CLOB : 문자데이터(4G Bytes) --자바에서는 문자열이 길면 CLOB
  예) DATA CLOB

--문자 이외에는 RAW/ LONG RAW/ BLOB 사용

       예) 회원테이블만들기
         - 아이디 (기본키)
 - 비밀번호
 - 이메일
 - 나이
 - 가입일

CREATE TABLE MEMBER
(
ID VARCHAR2(15) PRIMARY KEY, -- 기본키 설정
PWD VARCHAR2(10),
EMAIL VARCHAR2(15),
AGE NUMBER(3),
REGDATE DATE
);
 
Q1-- 임의의 회원정보를 3명 추가 해보세요.
INSERT INTO MEMBER(ID,PWD,EMAIL,AGE)
VALUES('JHTA1',111,'JHTA1@HTA.NET',29);

INSERT INTO MEMBER(ID,PWD,EMAIL,AGE)
VALUES('JHTA2',222,'JHTA2@HTA.NET',30);

INSERT INTO MEMBER(ID,PWD,EMAIL,AGE,)
VALUES('JHTA3',333,'JHTA3@HTA.NET',31,to_date('2020/03/01','yyyy/mm/dd'));

to_date('2020/03/01','yyyy/mm/dd')

ID                             PWD                  EMAIL                                 AGE       REGDATE
------------------------------ -------------------- ------------------------------ ---------- --------
JHTA1                          111                  JHTA1@HTA.NET                          29
JHTA2                          222                  JHTA2@HTA.NET                          30
JHTA3                          333                  JHTA3@HTA.NET                          31

Q2-- 회원정보를 임의의 데이터로 수정해 보세요.

UPDATE MEMBER
SET REGDATE = SYSDATE;

UPDATE MEMBER SET PWD='0000' WHERE ID='BBB';


Q3-- 임의의 조건에 맞는 회원을 삭제해 보세요.

DELETE FROM MEMBER WHERE PWD=333;

      3) 테이블삭제
        DROP TABLE 테이블명;

DROP TABLE MEMBER;

자식테이블이 있는 부모테이블의 경우 바로 부모테이블 삭제 안됨
--자식테이블 먼저 삭제 후 부모테이블 삭제

DROP TABLE GRADE; --자식
DROP TABLE STUDENT; --부모

      4) 테이블 구조 변경하기

        <1> 컬럼추가
   ALTER TABLE 테이블명 ADD(컬럼명 타입);
   예) ALTER TABLE EMP ADD(EMAIL VARCHAR2(15));

        <2> 컬럼변경
   ALTER TABLE 테이블명 MODIFY(컬럼명 타입);
   예) ALTER TABLE EMP MODIFY(EMAIL VARCHAR2(20));

        <3> 컬럼명 변경
   ALTER TABLE 테이블명 RENAME COLUMN 컬럼명 TO 바꿀컬럼명;
   예) ALTER TABLE EMP RENAME COLUMN EMAIL TO MAIL;

        <4> 컬럼삭제
   ALTER TABLE 테이블명 DROP COLUMN 컬럼명;
   예) ALTER TABLE EMP DROP COLUMN MAIL;


<8> 제약조건<***>
        - 테이블의 해당 컬럼에 잘못된 값이 입력/변경/삭제되는 것을 방지하기 위해
  설정되는 조건(무결성 제약조건)
- 결함이 없는 데이터를 관리하기 위함

       1) 종류
          (1) PRIMARY KEY (기본키)
   - **하나의 테이블에 하나만 존재**하며 각 행을 식별하기 위한 용도로 사용
   - NULL값을 허용하지 않고 중복값을 허용안함(NOT NULL + UNIQUE KEY)
         (2) FOREIGN KEY (외래키,참조키)
   - 부모테이블의 특정 컬럼(기본키)를 참조하는 컬럼
   - ***부모테이블에 참조하는 값이 없으면 오류가 발생한다***.
         (3) UNIQUE KEY(유일키) --중복 X
   - 컬럼의 모든 값이 유일해야 하는 경우에 사용. 중복데이터를 허용하지 않음
   - NULL은 허용됨(해당 유일키가 없는경우 안 넣어도 됨)-ex)이메일,전화번호가 없는 회원
         (4) CHECK 제약조건(많이사용안됨)
   - 조건에 맞는 데이터만 입력되도록 조건을 부여하는 제약조건
         (5) NOT NULL 조건(많이사용됨)
   - NULL값을 허용하지 않는 컬럼에 설정(ex: 회원가입시 이름 필수)
  
          예1) 제약조건에 이름을 부여하지 않은 경우
 CREATE TABLE DEPT1
 (
DEPTNO NUMBER(2) PRIMARY KEY,
DNAME VARCHAR2(15) DEFAULT '인사부',
LOC CHAR(9) CHECK(LOC IN('서울','부산'))
 );

INSERT INTO DEPT1(DEPTNO,DNAME,LOC) VALUES(1, '총무부', '서울');
INSERT INTO DEPT1(DEPTNO,LOC) VALUES(2, '부산');
INSERT INTO DEPT1 VALUES(3, '영업부', '서울');

          예2) 
           CREATE TABLE EMP1
          (
EMPNO NUMBER(4) PRIMARY KEY,
ENAME VARCHAR2(15) NOT NULL,
JUMIN CHAR(13) UNIQUE,
DEPTNO NUMBER(2) REFERENCES DEPT1(DEPTNO) -- 외래키설정
           );

INSERT INTO EMP1 VALUES(99,'김포프','1234561098765',1);

          예3) 제약조건에 이름을 부여하기 - 컬럼레벨과 테이블레벨이 있다.
           - 컬럼레벨로 이름을 부여한 예
CREATE TABLE DEPT2
(
DEPTNO NUMBER(2) CONSTRAINT PK_DEPT2_DEPTNO PRIMARY KEY,
DNAME VARCHAR2(15),
LOC VARCHAR2(15)
);
- 테이블레벨로 이름을 부여한 예
CREATE TABLE EMP2
(
EMPNO NUMBER(4),
ENAME VARCHAR2(15) CONSTRAINT NN_NAME NOT NULL,
DEPTNO NUMBER(2),
CONSTRAINT PK_EMP2_EMPNO PRIMARY KEY(EMPNO),
CONSTRAINT FK_EMP2_DEPTNO FOREIGN KEY(DEPTNO) REFERENCES DEPT2
);

         예3) 두 개이상의 컬럼이 PK로 설정된다면 테이블레벨로 설정해야 한다.
EX) 학생번호,점수 묶어서 성적번호로 처리
<두개 테이블 만들어서 INSERT넣고 테스트하기>
       
           CREATE TABLE MYSTUDENT
(
STUNUM NUMBER(4), -- 학생번호
TERM VARCHAR2(5), -- 학기
SCORE NUMBER(3) NOT NULL,
CONSTRAINT PK_STUDENT PRIMARY KEY(STUNUM,TERM) -- 두개의 컬럼을 PK로 
설정
);


        2) 제약조건 추가하기/삭제하기
        - 제약조건은 수정은 안되고 삭제와 추가가 가능하다.
예1) 제약조건 삭제하기
 ALTER TABLE EMP2 DROP CONSTRAINT PK_EMP2_EMPNO;
예2) 제약조건 추가하기
 ALTER TABLE EMP2 ADD CONSTRAINT PK_EMP2_EMP PRIMARY KEY(EMPNO);

+ Recent posts