데이터의 정의, 데이터와 정보의 차이, 빅데이터의 일반적인 특징

데이터와 정보

 

데이터(정형 데이터(테이블 형태) : 엑셀, 비정형 데이터)

  • 문자, 숫자, 사진, 영상, 음성 등의 형태로 된 의미 단위
  • 보통 연구나 조사 등의 바탕이 되는 재료를 말하며, 자료를 의미 있게 정리하면 정보

데이터의 어원

  • 라틴어의 단어 Datum의 복수형인 Data에서 유래
  • Data의 본래 뜻은 '주어진 것', 원천 데이터(로우 데이터,raw data)
  • '자료'라고 불림

질적 데이터

Qualitative Data, 수치로 측정이 불가능한 데이터    ex) 설문지에 대한 대답, 인터뷰, 성별, 종교, 직업 등

=> 데이터를 시각화하거나 수치화하는 과정에서 양적 데이터가 되기도함.

수치 관계가 없다.

 

양적 데이터 (인공지능이나 빅데이터에서 많이 사용)

Quantitative Data, 수치로 측정이 가능한 데이터    ex) 온도, IQ, 혈압, 맥박, 물건의 가격, 사물의 길이, 재무비율 등

 

정보

  • 의사 결정을 지원하는 모든 종류의 가공된 자료 혹은 지식
  • 데이터와 정보는 서로 교환되어 사용하는 경우가 많음
  • 데이터와 정보의 차이점을 알아두는 것이 좋음

 

데이터 정보
의미 단위의 모음 가공된 자료와 지식의 모음
구조화되어 있지 않음 구조화되어 있음
유용하지 않을 수 있음 의사결정에 유용함
정보에 의존하지 않음 데이터 없이 존재할 수 없음
테이블, 그래프 형식으로 표현됨 언어로 표현됨
학생들의 시험 점수 (70점, 80점,...) 반 또는 학교의 평균점수, 교육 방식을 정하는 의사결정에 유용하게 사용될 수 있음

 

유용한 데이터들을 이용해서 정보를 만듦

데이터 수집: 케글, 공공데이터 포털 등 출처들을 많이 알고 있는 것이 중요

 

데이터

70, 76, 95, 45, 92, 84,...

 

정보

A 고등학교 학생들의 수학 점수가 70, 76, 95, 45, 92, 84,...

->A 고등학교 학생들의 수학 시험 평균 점수는 82점

->A 고등학교는 다른 고등학교에  비해 성적이 우수

 

이미지+ 텍스트+ 수치(양적 데이터) =(처리, 가공)=> 정보   //파이프라인 구축

 


빅데이터: 기존의 관리 및 분석체계로는 감당할 수 없을 정도로 거대한 데이터의 집합(1테라 바이트 이상) (2012년 세계 10대 기술 선정), 데이터 안에 빅데이터 존재

 

빅데이터의 어원

1990년대부터 사용되어 왔으며, 존 메쉬가 처음 사용한 용어

메쉬가 수많은 소규모 모임에서 빅데이터의 개념을 설명하고 회사의 투자 설명에서도 활용한 기록이 남아 있음

 

빅데이터의 특징 - 3V

  • 용량(Volume): 일반적으로 1TB(TeraByte)에서 1PT(PetaByte)로 정의
  • 다양성(Variety): 정형 데이터뿐만 아니라, 비정형 데이터와 같은 다양한 형태의 데이터도 같이 포함
  • 속도(Velocity): 데이터의 생산, 처리, 분석되는 속도가 보장됨

빅데이터 분석 기술

수집된 빅데이터에서 유용한 정보를 얻기 위해 분석하는 기술

텍스트마이닝(텍스트 분석 분야, 분류, 생성(챗봇), 변환), 머신러닝(ML, 머신러닝 안에 딥러닝), 딥러닝(DL), 자연어 처리, 비전 러닝(이미지 데이터 분석, 영상분석) 등

 

빅데이터 표현 기술

  • 수집된 빅데이터의 특성을 파악하기 위해 시각화(그래프)하는 기술
  • 디자인적 요소를 결합하여 인포그래픽, 인터렉티브, 대쉬보드 등 수많은 방법들로 표현

 

'빅데이터 분석' 카테고리의 다른 글

빅데이터 분석도구  (0) 2023.07.23
해외 빅데이터 활용 사례  (0) 2023.07.23
국내 빅데이터 활용 사례  (0) 2023.07.23
빅데이터 분석 프로세스  (0) 2023.07.23
빅데이터 분석 소개  (0) 2023.07.01

트리거: 서브 프로그램 단위의 하나인 TRIGGER는 테이블, 뷰, 스키마 또는 데이터베이스에 관련된 PL/SQL 불록 ( 또는 프로시저)으로 관련된 특정 사건(EVENT)이 발생될 때마다 묵시적(자동)으로 해당 PL/SQL 블록이 실행

데이터 베이스 내에 오브젝트로서 저장되어 관리되고, 사용자가 지정해서 실행을 할 수 없을며, 오직 TRIGGER 생성시 정의한 특정 사건(EVENT)에 의해서만 묵시적인 자동 실행(FIRE)이 이루어진다.

 

TRIGERR 몸체(실행부)에 TCL 명령(COMMIT, ROLLBACK,SAVEPOINT 명령)이 포함될 수 없다.

 

트리거란 특정 테이블의 데이터에 변경이 가해졌을 때 자동으로 수행되는 저장 프로시저

저장 프로시저는 필요할 때마다 사용자가 직접 EXECUTE 명령어로 호출해야 하지만 트리거는 테이블의 데이터가 INSERT, UPDATE, DELETE문에 의해 변경 될 때 자동으로 수행. (트리거를 사용자가 직접 실행X)

 

CREATE TRIGGER TRIGGER_NAME
TIMING[BEFORE|AFTER] --1
EVENT[INSERT|UPDATE|DELETE] --2
ON TABLE_NAME
[FOR EACH ROW]
[WHEN CONDITIONS]
BEGIN
	STATEMENT
END

 

① 트리거의 타이밍(트리거의 동작 시점을 설정)

[BEFORE] 타이밍은 어떤 테이블에 INSERT, UPDATE, DELETE 문이 실행될 때 해당 문장이 실행되기 전에 트리거가 가지고 있는 BEGIN ~ END 사이의 문장을 실행한다. [AFTER] 타이밍은 INSERT, UPDATE, DELETE 문이 실행되고 난 후에 트리거가 가지고 있는 BEGIN ~ END 사이의 문장 실행

 

②트리거의 이벤트(트리거 동작을 위한 이벤트 종류를 정의하는 단계)

트리거의 이벤트는 사용자가 어떤 DML(INSERT, UPDATE, DELETE)문을 실행했을 때 트리거를 발생시킬 것인지 결정, ON 테이블명은 트리거가 주목하는 대상 테이블을 정의

 

③ 트리거의 유형 (FOR EACH ROW에 의해 문장 레벨 트리거와 행 레벨 트리거로 나눔)

FOR EACH ROW 생략 - 문장 레벨 트리거 (영향을 받는 행이 전혀 없더라고 TRIGGER가 한번은 실행. TRIGGER 작업이 영향을 받는 행의 데이터 또는 TRIGGER 이벤트 자체에서 제공하는 데이터에 종속되지 않은 경우 유용)

FOR EACH ROW 기술 - 행 레벨 트리거 (추가되는 행의 수만큼 트리거가 동작, 행 내에서 이벤트 발생되는걸 기준으로 트리거의 감시, 보완 범위를 정함, 영향을 받는 행의 데이터나 TRIGGER 이벤트 자체에서 제공하는 데이터에 종속되는 경우 유용)

 

④ :NEW & :OLD

행 레벨 트리거에서 컬럼의 실제 데이터 값을 제어하는데 사용되는 연산자

INSERT 문: 입력된 컬럼의 값 :NEW

DELETE문: 삭제되는 컬럼의 값 :OLD,

UPDATE문: 변경 전 컬럼 데이터 값 :OLD, 수정할 새로운 데이터값 :NEW

 

⑤ 트리거의 몸체 (BEGIN ~ END)

해당 타이밍에 해당 이벤트가 발생하게 되면 실행될 기본 로직이 포함되는 부분으로 BEGIN ~ END에 기술

 

-트리거의 사용목적

데이터베이스 테이블을 생성하는 과정에서 참조 무결성과 데이터 무결성 등의 복잡한 제약 조건을 생성하는 경우
데이터베이스 테이블의 데이터에 생기는 작업을 감시, 보완
데이터베이스 테이블에 생기는 변화에 따라 필요한 다른 프로그램을 실행하는 경우
불필요한 트랜잭션을 금지하기 위해
컬럼의 값을 자동으로 생성되도록 하는 경우

 

FUNCTION: 값을 반환하는 명명된PL/SQL BLOCK으로 오라클 내장 함수와 같이 SQL 표현식의 일부로 사용하여 복잡한 SQL문을 간단한 형태로 사용 가능. 값을 반환하는 RETURN이 반드시 포함되며 반드시 하나의 값을 반환

내장 함수와 프로시저는 문법이나 특징이 거의 비슷하지만 차이점은 프로시저는 정해진 작업은 수행한 후 결과를 반환 할 수도 있고(OUT, IN OUT 모드 사용 시) 반환하지 않고 그냥 종료할 수도 있지만 함수는 정해진 작업을 수행한 후 결과를 돌려준다(RETURN)는 부분

RETURN의 데이터 타입: CHAR, DATE, NUMBER

 

CREATE [OR REPLACE] FUNCTION FUNCTION명
(매개변수 1 데이터타입, 매개변수2 데이터타입...)
RETURN 데이터타입 -- 함수가 반환할 데이터 타입 지정. 크기는 지정할 수 없다.
IS 
	지역변수 (선언)
BEGIN
	실행부
    RETURN 반환값;	--매개변수를 받아 특정 연산을 수행한 후 반환할 값 명시
    [EXCEPTION 예외 처리부]
END [함수이름];
/

 

PL/SQL 예외

컴파일 에러: PL/SQL 블록이 PARSE 되는 동안에 오타등으로 인하여 발생되는 에러

런타임 에러: PL/SQL 블록이 실행되는 동안에 발생되는 에러 (오라클에서는 예외(EXCEPTION)라고 함)

 

오라클의 예외 2가지

오라클 예외, 사용자에 의해 정의 되는 사용자 정의 예외(USER-DEFINED EXCEPTION)

 

-미리 정의되어 있는 오라클 예외들

NO_DATA_FOUND : PL/SQL SELECT문이 한건도 리턴하지 못했을 경우 발생

PROGRAM_ERROR : PL/SQL 이 내부적인 문제를 가지고 있는 경우

TOO_MANY_ROWS : PL.SQL SELECT 문이 두 건 이상의 행을 리턴했을 때

VALUE_ERROR : 산술, 변환, 절삭 또는 크기 제약에 에러가 생겼을 때 발생되는 예외

 

EXCEPTION
WHEN EXCEPTION1 [OR EXCEPTION2...] THEN
	STATEMENT1, 
    	STATEMENT2;
...
[WHEN EXEPTION3 [OR EXCEPTION4...] THEN
	STATEMENT3;
    	STATEMENT4;
 ...]

 

'DataBase+SQL' 카테고리의 다른 글

오라클 데이터베이스 페이징 처리  (0) 2023.08.30
PreparedStatement  (0) 2023.06.28
SQL 반복문, 커서  (0) 2023.06.27
PL/SQL  (0) 2023.06.26
MVIEW, 시퀀스  (0) 2023.06.23

1.Hello World

Hello World!를 출력하시오.

 

public class Main {
	public static void main(String args[]) {
		System.out.println("Hello World!");
	}
}

 

2. A+B

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

첫째 줄에 A+B를 출력한다.

 

import java.util.*;
public class Main {
	public static void main(String args[]) {
		Scanner input = new Scanner(System.in);
		int A=input.nextInt();
		int B=input.nextInt();
		
		System.out.print(A+B);
		
	}
}

 

3. A-B

두 정수 A와 B를 입력받은 다음, A-B를 출력하는 프로그램을 작성하시오.

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

첫째 줄에 A-B를 출력한다.

 

import java.util.*;

public class Main {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int A=input.nextInt();
		int B=input.nextInt();
		
		System.out.print(A-B);
	}
}

 

4.  A×B

두 정수 A와 B를 입력받은 다음, A×B를 출력하는 프로그램을 작성하시오.

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

첫째 줄에 A×B를 출력한다.

 

import java.util.*;

public class Main{
	public static void main(String args[]) {
		Scanner input = new Scanner(System.in);
		
		int A=input.nextInt();
		int B=input.nextInt();
		
		System.out.print(A*B);
	}
}

 

5.A/B

두 정수 A와 B를 입력받은 다음, A/B를 출력하는 프로그램을 작성하시오.

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

첫째 줄에 A/B를 출력한다. 실제 정답과 출력값의 절대오차 또는 상대오차가 10-9 이하이면 정답이다.

 

import java.util.*;

public class Main {
	public static void main(String args[]) {
		Scanner input = new Scanner(System.in);
		
		double A=input.nextDouble();
		double B=input.nextDouble();
		
		System.out.print(A/B);
	}
}

 

6. 사칙연산

두 자연수 A와 B가 주어진다. 이때, A+B, A-B, A*B, A/B(몫), A%B(나머지)를 출력하는 프로그램을 작성하시오. 

두 자연수 A와 B가 주어진다. (1 ≤ A, B ≤ 10,000)

첫째 줄에 A+B, 둘째 줄에 A-B, 셋째 줄에 A*B, 넷째 줄에 A/B, 다섯째 줄에 A%B를 출력한다.

 

import java.util.Scanner;
public class Main {
	public static void main(String args[]) {
		Scanner input = new Scanner(System.in);
		
		int A=input.nextInt();
		int B=input.nextInt();
		System.out.println(A+B);
		System.out.println(A-B);
		System.out.println(A*B);
		System.out.println(A/B);
		System.out.println(A%B);
	}
}

 

7.??!

준하는 사이트에 회원가입을 하다가 joonas라는 아이디가 이미 존재하는 것을 보고 놀랐다. 준하는 놀람을 ??!로 표현한다. 준하가 가입하려고 하는 사이트에 이미 존재하는 아이디가 주어졌을 때, 놀람을 표현하는 프로그램을 작성하시오.

첫째 줄에 준하가 가입하려고 하는 사이트에 이미 존재하는 아이디가 주어진다. 아이디는 알파벳 소문자로만 이루어져 있으며, 길이는 50자를 넘지 않는다.

첫째 줄에 준하의 놀람을 출력한다. 놀람은 아이디 뒤에 ??!를 붙여서 나타낸다.

 

import java.util.Scanner;
public class Main {
	public static void main(String args[]) {
		Scanner input = new Scanner(System.in);
		String id= input.next();
		
		System.out.println(id+"??!");
	}
}

 

8. 1998년 생인 내가 태국에서는 2541년생?!

ICPC Bangkok Regional에 참가하기 위해 수완나품 국제공항에 막 도착한 팀 레드시프트 일행은 눈을 믿을 수 없었다. 공항의 대형 스크린에 올해가 2562년이라고 적혀 있던 것이었다.

불교 국가인 태국은 불멸기원(佛滅紀元), 즉 석가모니가 열반한 해를 기준으로 연도를 세는 불기를 사용한다. 반면, 우리나라는 서기 연도를 사용하고 있다. 불기 연도가 주어질 때 이를 서기 연도로 바꿔 주는 프로그램을 작성하시오.

서기 연도를 알아보고 싶은 불기 연도 y가 주어진다. (1000 ≤ y ≤ 3000)

불기 연도를 서기 연도로 변환한 결과를 출력한다.

 

import java.util.Scanner;
public class Main {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		int y=sc.nextInt();
		System.out.println(y-543);
	}
}

 

9.나머지

(A+B)%C는 ((A%C) + (B%C))%C 와 같을까?

(A×B)%C는 ((A%C) × (B%C))%C 와 같을까?

세 수 A, B, C가 주어졌을 때, 위의 네 가지 값을 구하는 프로그램을 작성하시오.

첫째 줄에 A, B, C가 순서대로 주어진다. (2 ≤ A, B, C ≤ 10000)

첫째 줄에 (A+B)%C, 둘째 줄에 ((A%C) + (B%C))%C, 셋째 줄에 (A×B)%C, 넷째 줄에 ((A%C) × (B%C))%C를 출력한다.

 

import java.util.Scanner;
public class Main{
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		int A=sc.nextInt();
		int B=sc.nextInt();
		int C=sc.nextInt();
		System.out.println((A+B)%C);
		System.out.println(((A%C)+(B%C))%C);
		System.out.println((A*B)%C);
		System.out.println(((A%C)*(B%C))%C);
	}
}

 

10. 곱셈

(세 자리 수) × (세 자리 수)는 다음과 같은 과정을 통하여 이루어진다.

(1)과 (2)위치에 들어갈 세 자리 자연수가 주어질 때 (3), (4), (5), (6)위치에 들어갈 값을 구하는 프로그램을 작성하시오.

첫째 줄에 (1)의 위치에 들어갈 세 자리 자연수가, 둘째 줄에 (2)의 위치에 들어갈 세자리 자연수가 주어진다.

첫째 줄부터 넷째 줄까지 차례대로 (3), (4), (5), (6)에 들어갈 값을 출력한다.

 

import java.util.Scanner;
public class Main{
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		int A=sc.nextInt();
		int B=sc.nextInt();
		
		int B1=B%10;
		int B2=(B%100)/10;
		int B3=B/100;
		int sum1=A*B1;
		int sum2=A*B2;
		int sum3=A*B3;
		System.out.println(sum1);
		System.out.println(sum2);
		System.out.println(sum3);
		System.out.println(sum1+sum2*10+sum3*100);
	}
}

 

11.꼬마 정민

꼬마 정민이는 이제 A + B 정도는 쉽게 계산할 수 있다. 이제 A + B + C를 계산할 차례이다!

첫 번째 줄에 A, B, C (1 ≤ A, B, C ≤ 1012)이 공백을 사이에 두고 주어진다.

A+B+C의 값을 출력한다.

 

import java.util.Scanner;
public class Main {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		Long A=sc.nextLong();
		Long B=sc.nextLong();
		Long C=sc.nextLong();
		
		System.out.println(A+B+C);
		sc.close();
	}
}

반복문: SQL문을 반복작으로 여러번 실행하고자 할 때 사용, PL/SQL에서는 다양한 반복문이 사용

  • BASIC LOOP: 조건없이 반복 작업
  • FOR LOOP: COUNT를 기본으로 작업
  • WHILE LOOP: 조건을 기본으로 작업
  • EXIT: LOOP를 종료

BASIC LOOP: LOOP에서 END LOOP 사이를 계속 반복해서 실행(무한 루프), 여기서 빠져나가려면 EXIT문을 사용, 조건에 따라 루프를 종료할 수 있도록 WHEN 절을 덧붙일 수 있다.

LOOP
	STATEMENT1;
    	STATEMENT2;
    	EXIT [WHEN CONDITION];
END LOOP;

 

FOR LOOP: 반복되는 횟수가 정해진 반복문을 처리, 사용되는 인덱스는 정수로 자동 선언, 자동적으로 1씩 증가 또는 감소(REVERSE는 1씩 감소)

 

FOR INDEX_COUNTER IN [REVERSE] LOWER_BOUND..UPPER_BOUND LOOP
	STATEMENT1,
    	STATEMENT2;
END LOOP;

END FOR가 아니라 END LOOP!

 

WHILE LOOP: 제어 조건이 TRUE인 동안만 일련의 문장을 반복하기 위해 사용

조건은 반복이 시작될 때 체크하게 되어 LOOP내의 문장이 한번도 수행하지 않을 수 있다.

LOOP을 시작할 때 조건이 FALSE이면 반복 탈출

WHILE 조건문 LOOP
	STATEMENT1;
    	STATEMENT2;
END LOOP;

 

커서(CURSOR): 오라클 서버에서는 SQL문을 실행할 때마다 처리(Parse, Execution)를 위한 메모리 공간(SQL 커서)을 사용.

사용자가 요청하는 데이터를 데이터베이스 버퍼 캐쉬에서 커서로 복사해 온 후 커서에서 원하는 데이터를 추출(Fetch) 원하는 작업을 하게 된다. 이 메모리 공간을 Private SQL Area.

특정 SQL문장을 처리한 결과를 담고 있는 영역을 가리키는 일종의 포인터.

커서를 사용하면 처리된 SQL문장의 결과 집합에 접근 가능

 

묵시적 커서: 오라클 내부에 자동으로 생성하는 커서

명시적 커서: 사용자가 직접 정의해서 사용하는 커서

 

커서열기(OPEN) - 패치(FETCH) - 커서닫기(CLOSE): 3단계로 진행

  1. 명시적 커서 선언 (CURSOR)
  2. 명시적 커서 오픈 (OPEN)
  3. 커서에서 데이터 추출 (FETCH)
  4. 커서 사용 종료 (CLOSE)

DECLARE CURSOR(커서 선언): 사용할 커서를 선언부에 직접 정의, 사용할 커서에 이름을 부여하고 이 커서에 대한 쿼리를 선언

CURSOR 커서명 IS 커서에 담고 싶은 내용을 가져오는 서브쿼리(다중행);

CURSOR A1 IS SELECT * FROM DEPARTMENTS;

 

OPEN CUSOR(커서 열기) : 질의를 수행하고 검색 조건을 충족하는 모든 행으로 구성된 결과 셋(커서 선언 시 기술했던 서브쿼리를 수행해서 데이터를 커서로 가져오는 과정)을 생성하기 위해 CURSOR를 OPEN.

CURSOR는 결과 셋에서 첫번째 행을 가리킨다.

OPEN 커서명;
OPEN C1;

 

FETCH CURSOR(패치 단계에서 커서 사용): 정의한 커서를 열고 난 후에야 SELECT 문의 결과로 반환되는 로우에 접근 가능. 결과 집합의 로우 수는 보통 1개 이상이므로 전체 로우에 접근하기 위해서는 반복문을 사용

  • FETCH문은 결과 셋에서 로우 단위로 데이터를 읽어들임
  • FETCH 후에 CURSOR는 결과 셋에서 다음 행으로 이동
FETCH 커서명 INTO 변수들
INTO {VARIABLE1 [, VARIABLE2, ...]};

LOOP
	FETCH C1 INTO VDEPARTMENTS.DEPARTMENT_ID, VDEPARTMENTS.DEPARTMENT_NAME, VDEPARTMENTS.LOCATION_ID;
    EXIT WHER C1%NOTFROUND;
END LOOP;

 

얻어진 여러개의 행에 대한 결과값을 모두 처리하여면 반복문에 FETCH문을 기술

NOTFOUND: 커서의 상태를 알려주는 속성 중에 하나, 커서 영역의 자료가 모두 FETCH 되었다면 TRUE를 되돌린다.

즉 커서 C1 영역의 자료가 모두 FETCH되면 반복문 탈출 

 

커서의 상태

속성 의미
%NOTFOUND 커서 영역의 자료가 모두 FETCH 되었다면 TRUE
%FOUND 커서 영역에 FETCH 되지 않은 자료가 있다면 TRUE
%ISOPEN 커서가 OPEN된 상태이면 TRUE
%ROWCOUNT 커서가 얻어 온 레코드의 개수

 

CLOSE CURSOR(커서 닫기): CLOSE 문장은 CURSOR를 사용할 수 없게 하고 결과 셋의 정의를 해제

CLOSE CURSOR_NAME;
CLOSE C1;

 

CURSOR와 FOR LOOP(묵시적으로 CURSOR에서 행을 처리)

LOOP에서 각 반복마다 CURSOR를 열고 행을 인출(FETCH)하고 모든 행이 처리되면 자동으로 CURSOR가 CLOSE되므로 사용하기가 편리

 

DECLARE
    VDEPARTMENTS DEPARTMENTS%ROWTYPE;
    CURSOR C1 --커서 이름
    IS
    SELECT DEPARTMENT_ID, DEPARTMENT_NAME, LOCATION_ID
    FROM DEPARTMENTS; --부서 테이블의 전체 내용을 조회
BEGIN
    DBMS_OUTPUT.PUT_LINE('부서번호 / 부서명 / 지역명');
    DBMS_OUTPUT.PUT_LINE('-----------------------------------');
    
    OPEN C1;
    --오픈한 C1커서가 SELECT문에 의해 검색된 한개의 행의 정보를 읽어온다. 
    --포인터가 있는 레코드 한개
    LOOP --읽어온 정보는 INTO뒤에 기술한 변수에 저장
        FETCH C1 INTO VDEPARTMENTS.DEPARTMENT_ID, VDEPARTMENTS.DEPARTMENT_NAME,
        VDEPARTMENTS.LOCATION_ID;
        EXIT WHEN C1%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(VDEPARTMENTS.DEPARTMENT_ID ||' '||
        RPAD(VDEPARTMENTS.DEPARTMENT_NAME, 20) ||' '||VDEPARTMENTS.LOCATION_ID);
    END LOOP;
    DBMS_OUTPUT.PUT_LINE(CONCAT('읽어드린 레코드수 : ', C1%ROWCOUNT));
    CLOSE C1;
END;
/

 

CURSOR와 FOR LOOP(묵시적으로 CURSOR에서 행을 처리.)

LOOP에서 각 반복마다 CURSOR를 열고 행을 인출(FETCH)하고 모든 행이 처리되면 자동으로 CURSOR가 CLOSE되므로 사용하기가 편리.

 

FOR RECORD_NAME IN CURSOR_NAME LOOP
--명시적 커서의 OPEN, FETCH가 자동적으로 수행됨
	STATEMENT1;
    STATEMENT2;
END LOOP	--루프문을 빠져 나갈 때 자동적으로 커서가 CLOSE 됨.

 

커서변수: 한 개이상의 쿼리를 연결해 사용 가능, 변수처럼 커서 변수를 함수나 프로시저의 매개변수로 전달

● 커서 변수 선언

TYPE 커서_타입명 IS REF CURSOR;	--커서 타입선언(생략)
커서_변수명 커서_타입명;	-- 커서변수 선언

 

오라클에서 제공하는 커서 타입(결과 집합이 고정되어 있지 않으므로)인 SYS_REFCURSOR이란 타입을 사용하는 것,

따라서 SYS_REFCURSOR를 사용할 때는 별도로 커서 타입을 선언할 필요없이 다음과 같이 커서 변수만 선언하면 된다.

커서변수 SYS_REFCURSOR;	--커서변수 선언

 

● 커서변수의 사용

① 커서 변수와 커서 정의 쿼리문 연결

커서를 정의하는 쿼리가 있어야 하는데 커서변수와 쿼리문을 연결할 때 다음과 같이 OPEN...FOR 구문을 사용

OPEN 커서변수명 FOR SELECT 문;

 

② 커서 변수에서 결과집합 가져오기

커서를 구성하는 쿼리에 커서 변수까지 연결했으니 커서 변수에 결과 집합ㄴ을 가져오는 패치 작업이 남았는데, 이때도 FETCH문 사용

FETCH 커서변수명 INTO 변수1, 변수2,...;

 

● 커서변수의 사용

DECLARE
    VFIRST_NAME EMPLOYEES.FIRST_NAME%TYPE;
    --TYPE EMPLOYEESCURSOR IS REF CURSOR;   --커서 타입 선언
    --VEMPLOYEES EMPLOYEESCURSOR;   --커서 변수 선언
    VEMPLOYEES SYS_REFCURSOR;    --오라클 서버가 제공하는 커서타입(SYS_REFCURSOR)으로 커서변수 선언.
BEGIN
    --커서 변수를 사용한 커서 정의 및 오픈
    OPEN VEMPLOYEES FOR SELECT FIRST_NAME FROM EMPLOYEES WHERE DEPARTMENT_ID = 90;
    
    --LOOP문
    LOOP
        --커서 변수를 사용해 결과 집합을 EMPNAME 변수에 할당
        FETCH VEMPLOYEES INTO VFIRST_NAME;
        EXIT WHEN VEMPLOYEES%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('사원명 : ' ||VFIRST_NAME);   --사원명을 출력
    END LOOP;
END;
/

 

ORACLE SUBPROGRAM

익명 블록 서브 프로그램
이름이 지정되지 않은 PL/SQL 블록 이름이 지정된 PL/SQL 블록
매번 사용시마다 컴파일 최초 실행될 때 한번만 컴파일
데이터베이스에 저장되지 않습니다. 데이터베이스에 저장
다른 응용프로그램에서 호출 불가 다른 응용프로그램에서 호출 가능
값 반환X 함수일 경우 값 RETURN, RETURN이 없는 함수 존재X
파라미터 사용X 파라미터 사용O

1) 저장 프로시저(Stored Procedure: 스토어드 프로시저)

프로시저 : 지정된 특정 처리를 실행하는 서브 프로그램의 한 유형.

저장 프로시저: 자주 사용되는 쿼리문을 모듈화시켜서 필요할 때마다 호출하여 사용하는 것

CREATE [OR REPLACE] PROCEDURE PRCEDURE_NAME
(매개변수1 [IN(MODE)] 자료형,	--MODE에 따라 프로시저를 호출 시 값을 전달 받거나 프로시저 호출 후
매개변수2 [OUT(MODE)] 자료형...)	--해당 매개 변수 값을 받아 사용, IN/OUT/IN OUT,IN은 생략 가능
--OUT은 생략 불가능
IS
	LOCAL_VARIABLE DECLARATION	--변수선언
BEGIN
	STATEMENT1;
END [PRCEDURE_NAME];

USER_SOURCE: 저장 프로시저를 작성한 후 사용자가 저장 프로시저가 생성되었는지 확인

 

① 매개 변수: 프로시저 이름 뒤에 ()를 기술하여 그 내부에 매개변수를 정의

변수명 모드 자료형

 

--프로시저 생성               프로시저명 ( 변수명         입력             자료형)
CREATE OR REPLACE PROCEDURE EMPPROC02 (VDEPARTMENT_ID IN EMPLOYEES.DEPARTMENT_ID%TYPE)
IS
    CURSOR C1
    IS
    SELECT * FROM EMPLOYEES WHERE DEPARTMENT_ID = VDEPARTMENT_ID;
BEGIN
    DBMS_OUTPUT.PUT_LINE('사원번호 / 사원명 / 급여');
    DBMS_OUTPUT.PUT_LINE('---------------------------------------');
    FOR VEMPLOYEES IN C1 LOOP
        DBMS_OUTPUT.PUT_LINE(VEMPLOYEES.EMPLOYEE_ID||' / '||VEMPLOYEES.FIRST_NAME||' / ' ||
                            VEMPLOYEES.SALARY);
    END LOOP;
END;
/
SHOW ERROR;

 

--프로시저 실행
--[형식]
--EXECUTE 또는 EXEC 프로시저;
--위 코드는 주석과 함께 명시할 수 없다.
--부서번호가 90
EXECUTE EMPPROC02(90);

 

IN 모드 OUT 모드 (RETURN과 같은 역할) IN OUT 모드
기본모드. 명시적으로 지정 명시적으로 지정
값이 서브 프로그램에 전달됨 값이 호출환경에 반환 값이 서브 프로그램에도 전달되고 호출환경에도 반환
실제 파라미터가 리터럴 표현식, 상수 또는 초기화된 변수가 될 수 X 변수만 사용가능 변수만 사용가능
기본값을 할당할 수 있음 기본값 할당 불가 기본값 할당 불가

 

● IN MODE 매개변수: 실행환경에서 서브 프로시저로 값 전달.

부서별로 SALARY 인상. 부서코드가 10이면 10% 인상, 20이면 20%인상, 나머지 동결.

 

CREATE OR REPLACE PROCEDURE EMPPROC_INMODE
(VDEPARTMENT_ID IN EMPLOYEES01.DEPARTMENT_ID%TYPE)
IS
BEGIN
    UPDATE EMPLOYEES01 SET SALARY = DECODE(VDEPARTMENT_ID, 10, SALARY*1.1, 20, 
    SALARY*1.2, SALARY)
    WHERE DEPARTMENT_ID = VDEPARTMENT_ID;
    COMMIT;
    DBMS_OUTPUT.PUT_LINE('수정이 완료되었습니다.');
END EMPPROC_INMODE;
/

 

PreparedStatement

Connection 객체의 prepareStatement() 메소드를 사용하여 객체 생성

SQL문장이 미리 컴파일 되고 실행 시간동안 인수 값을 위한 공간을 확보한다는 점에서 Statement와 다름

각각의 인수에 대해 위치홀더(?)를 사용하여 SQL문장을 정의할 수 있게 함

 

PreparedStatement pstmt = null;
try{
	String query = "INSERT INTO member(id, password, name)
    				VALUES(?,?,?)";	//?: 바인딩 변수
    pstmt = conn.prepareStatement(query);
    pstmt.setString(1, "javauser");
    pstmt.setString(2, "java1234");
    pstmt.setString(3, "홍길동");
}catch(SQLException e){e.printStackTrace();}

 

'DataBase+SQL' 카테고리의 다른 글

PROCEDURE TRIGGER  (0) 2023.06.29
PreparedStatement  (0) 2023.06.28
PL/SQL  (0) 2023.06.26
MVIEW, 시퀀스  (0) 2023.06.23
뷰(VIEW)  (0) 2023.06.22

자주 사용하는 명령을 PL/SQL 구문을 이용하여 데이터베이스에 저장하고 필요할 때 호출하여 사용하는 방법 연습

1)PL/SQL: Oracle's Procedural Language extension to SQL의 약자

SQL문장에서 변수  정의, 조건처리(IF), 반복처리(LOOP, WHILE, FOR)등을 지원

DB에 직접 탑재되어 컴파일, 실행 => 성능 우수, DB 관련 처리를 할 때 수많은 기능을 제공, 일반 프로그래밍 언어적인 요소를 거의 다 가지고 있어서 실무에서 요구되는 절차적인 데이터 처리를 다 할 수 있음. 특히 SQL과 연동되어 막강할 기능 구현 가능

 

PL/SQL은 SQL에 없는 기능 제공

  • 변수 선언 가능
  • 비교 처리 가능
  • 반복 처리 가능

PL/SQL 기본 단위: 블록(BLOCK)=> 선언부, 실행부, 예외처리부 구성

                                                     => 이름이 없는 블록(익명 블록: 처음부터 마지막까지 한꺼번에 정의), 이름이 있는 블록                                                             (함수, 프로시저, 패키지) 구분

 

DECLEARE
	선언부(DECLARE SECTION)
    -변수나 상수를 선언
BEGIN
	실행부(EXECUTABLE SECTION)
    SQL문
    제어문, 반복문
    커서
EXCEPTION 
	예외 처리부(EXCEPTION SECTION)
END;
/

 

장점

  • 프로그램의 모듈화: 특정 프로그램을 Procedure, function, package등의  프로그램으로 만들어 여러 응용 프로그램을 만들시 공통으로 이용 및 관리 할 수 있다.
  • 관리의 용이
  • 네트워크 입출력 감소: 프로시저 등을 실행하는 구문만 데이터베이스에 보낼 수 있어 네트워크 입출력을 현격하게 줄일 수 있다.

특징

  • PL/SQL 블록 내에서는 한 문장이 종료할 때마다 세미콜론(;)을 사용
  • END 뒤에 ;을 사용하여 하나의 블록이 끝났다는 것을 명시
  • DECLARE나 BEGIN이라는 키워드로 PL.SQL 블록이 시작하는 것을 알 수 있다.
  • 단일 행 주석은 --이고 여러 행 주석을 /**/이다.
  • PL/SQL 블록은 행에 /가 있으면 종료

 

자바
자료형 변수 = 값;		--대입연산자
비교 연산자 ==		--비교

오라클
변수 자료형 := 값;	--대입
비교 연산자 =		--비교

SELECT 컬럼1, 컬럼2 INTO 변수1, 변수2	--변수에 데이터 담기
FROM 테이블
WHERE 조건문

 

모든 문장의 종결 기호는 세미콜론으로 명시, 대입 연산자로는 := 사용, 대입 연산자는 변수의 선언 시 및 변수의 대입에 이용

변수 자료형 := 값;

SELECT문에 의해 추출되는 DATA는 INTO절의 변수에 저장해서 처리

 

--'Hello World!' 출력
BEGIN
    DBMS_OUTPUT.PUT_LINE('Hello World!');       --DBMS_OUTPUT: Package, 오라클 문장 작은 따옴표
END;
/

 

보기 - DBMS 출력 - +에서 사용자 설정

 

DECLARE
    VEMPLOYEE_ID NUMBER(6);     --변수 자료형
    VFIRST_NAME VARCHAR2(20);
BEGIN
    VEMPLOYEE_ID := 105;
    VFIRST_NAME := 'David';
    
    DBMS_OUTPUT.PUT_LINE('사번 / 이름');
    DBMS_OUTPUT.PUT_LINE('-----------');
    DBMS_OUTPUT.PUT_LINE(VEMPLOYEE_ID || ' / ' || VFIRST_NAME);
END;
/

 

1) 변수

IDENTIFIER [CONSTANT] DATATYPE [NOT NULL] [:=|DEFAULT EXPRESSION];

 

구문 설명
IDENTIFIER 변수의 이름
CONSTANT 변수의 값을 변경할 수 없도록 제약
DATATYPE 자료형(데이터 타입)을 기술
-변수 데이터 타입: SQL 타입(NUMBER, CHAR, VARCHAR2,DATE,...) 과 PL/SQL 타입
-PL/SQL 데이터 타입: BOOLEAN, BINARY_INTEGER
NOT NULL 값을 반드시 포함하도록 하기 위해 변수를 제약
EXPRESSION LITERAL, 다른 변수, 연산자나 함수를 포함하는 표현식

 

PL/SQL에서 변수를 선언할 때 사용되는 자료형은 SQL에서 사용하던 자료형과 거의 유사

상수명 CONSTANT 데이터 타입 := 상수값;

IDENTIFIER := EXPRESSION;
DECLARE
	VAL_NUM NUMBER;
BEGIN
	VAL_NUM := 100;
    DBMS_OUTPUT.PUT_LINE(VAL_NUM);	--DBMS_OUTPUT: 패키지, PUT_LINE: 프로시저
END;
/

2] 스칼라 변수 / 레퍼런스 변수 : PL/ SQL에서 변수를 선언하기 위해 사용할 수 있는 데이터 형

 

스칼라: SQL에서의 자료형 지정과 거의 동일

--변수 자료형
VEMPLOYEE_ID NUMBER(6);
VFIRST_NAME VARCHAR2(20);

 

레퍼런스: %TYPE 속성과 %ROWTYPE 속성 사용, 이전에 선언된 다른 변수 또는 데이터베이스의 칼럼에 맞추어 변수를 선언하기 위해 %TYPE 속성을 사용

 

--변수 테이블. 컬럼(자료형 참조)%TYPE
VEMPLOYEE_ID EMPLOYEES.EMPLOYEE_ID%TYPE;
VFIRST_NAME EMPLOYEES.FIRST_NAME%TYPE;

%TYPE 속성을 사용하여 선언한 VEMPLOYEE_ID 변수는 EMPLOYEES 테이블의 EMPLOYEE_ID 칼럼의 자료형과 크기를 그대로 참조해서 정의

 

%ROWTYPE은 로우 단위로 참조(레코드 하나)

VEMPLOYEES EMPLOYEES%ROWTYPE;

 

%ROWTYPE의 장점: 칼럼의 개수와 데이터 형식을 모르더라도 지정 가능, SELECT 문장으로 로우 검색할 때 유리

 

3]PL/SQL에서 SQL 문장

PL/SQL의 SELECT 문은 INTO 절이 필요한데, INTO절에 데이터를 저장할 변수를 기술

SELECT절에 있는 칼럼은 INTO 절에 있는 변수와 1대1 대응을 하기에 개수와 데이터형, 길이가 일치하여야한다.

SELECT SELECT_LIST
INTO {VARIABLE_NAME1 [,VARIABLE_NAME2,...] |RECORD_NAME}
FROM TABLE_NAME
WHERE CONDITION;

 

 구문 설명
SELECT_LIST 열의 목록이며 행 함수, 그룹 함수, 표현식을 기술할 수 있다.
VARIABLE_NAME 읽어들인 값을 저장하기 위한 스칼라 변수
RECORD_NAME 읽어 들인 값을 저장하기 위한 PL/SQL RECORD 변수
CONDITION PL/SQL 변수와 상수를 포함하여 열명, 표현식, 상수, 비교 연산자로 구성되며 오직 하나의 값을 RETURN할 수 있는 조건이어야 한다.

 

4] 전체 레코드를 참조하기 위해서는 %ROWTYPE으로 선언

 

DECLARE 
    --레코드로 변수 선언
    VEMPLOYEES EMPLOYEES%ROWTYPE;
BEGIN
    --Lisa 사원의 정보를 레퍼런스 변수에 저장
    SELECT *
    INTO VEMPLOYEES
    FROM EMPLOYEES
    WHERE FIRST_NAME = 'Lisa';
    
    --레코드 변수에 저장된 사원 정보를 출력
    DBMS_OUTPUT.PUT_LINE('사원번호 : ' || TO_CHAR (VEMPLOYEES.EMPLOYEE_ID));
    DBMS_OUTPUT.PUT_LINE('이 름 : ' ||VEMPLOYEES.FIRST_NAME);
    DBMS_OUTPUT.PUT_LINE('급 여 : ' ||VEMPLOYEES.SALARY);
    DBMS_OUTPUT.PUT_LINE('입사일자 : ' || TO_CHAR(VEMPLOYEES.HIRE_DATE, 'YYYY-MM-DD'));
    DBMS_OUTPUT.PUT_LINE('부서번호 : ' || VEMPLOYEES.DEPARTMENT_ID);
END;
/

 

--예제 EMPLOYEES 테이블에 등록된 총 사원의 수와 급여의 합, 급여의 평균을 변수에 대입하여 출력
DECLARE
    VCNT NUMBER;
    VSUM NUMBER;
    VAVG NUMBER(10,2);
BEGIN
    SELECT COUNT(*), SUM(SALARY), AVG(SALARY) INTO VCNT, VSUM, VAVG
    FROM EMPLOYEES;
    
    DBMS_OUTPUT.PUT_LINE('총사원의 수 : ' || VCNT);
    DBMS_OUTPUT.PUT_LINE('급여의 합 : ' || VSUM);
    DBMS_OUTPUT.PUT_LINE('급여의 평균 : ' ||VAVG);
END;
/
--예제 Jack 사원의 직무, 급여, 입사일자, 부서명을 변수에 대입하여 출력
DECLARE
    VEMPLOYEES EMPLOYEES%ROWTYPE;
    VDEPARTMENTS DEPARTMENTS%ROWTYPE;
BEGIN
    SELECT JOB_ID, SALARY, HIRE_DATE, DEPARTMENT_NAME
    INTO VEMPLOYEES.JOB_ID, VEMPLOYEES.SALARY, VEMPLOYEES.HIRE_DATE, VDEPARTMENTS.DEPARTMENT_NAME
    FROM EMPLOYEES EMP INNER JOIN DEPARTMENTS DEPT
    ON EMP.DEPARTMENT_ID = DEPT.DEPARTMENT_ID
    WHERE FIRST_NAME='Jack';
    
    DBMS_OUTPUT.PUT_LINE('직무 : ' || VEMPLOYEES.JOB_ID);
    DBMS_OUTPUT.PUT_LINE('급여 : ' || VEMPLOYEES.SALARY);
    DBMS_OUTPUT.PUT_LINE('입사일자 : ' || TO_CHAR( VEMPLOYEES.HIRE_DATE, 'YYYY-MM-DD'));
    DBMS_OUTPUT.PUT_LINE('부서명 : ' || VDEPARTMENTS.DEPARTMENT_NAME);
END;
/

 

--사원 테이블 (EMPLOYEES01)에서 사원번호가 제인 큰 사원을 찾아낸 뒤 ,
--이 번호 +3번으로 아래의 사원을 사원테이블에 신규 입력하는 
--PL/SQL을 만들어 보자

--복사 테이블 생성
CREATE TABLE EMPLOYEES01
AS
SELECT * FROM EMPLOYEES;

DECLARE
    MAX_EMPLOYEE_ID EMPLOYEES01.EMPLOYEE_ID%TYPE;
BEGIN
    SELECT MAX(EMPLOYEE_ID) INTO MAX_EMPLOYEE_ID FROM EMPLOYEES01;
    
    INSERT INTO EMPLOYEES01 (EMPLOYEE_ID, FIRST_NAME, LAST_NAME, EMAIL, SALARY, HIRE_DATE,
                            MANAGER_ID, JOB_ID, DEPARTMENT_ID)
    VALUES (MAX_EMPLOYEE_ID +3, 'Olivia', 'Gee', 'Spring', 2800, SYSDATE, 100, 'PR_REP', 20);
    
    COMMIT;
END;
/
SELECT * FROM EMPLOYEES01;

 

3) 제어문: 조건에 의해 분기하는 선택문과 반복된 문장을 한번 기술하고도 여러변 수행하도록 하는 반복문이 있다.

 

1] IF ~ THEN ~ END IF: 특정 조건을 만족하면 처리를 하고, 그렇지 않으면 아무런 처리X

IF 조건문 THEN
	조건처리;
END IF;

 

2] IF ~ THEN ~ ELSE ~ END IF: 조건을 만족할 때의 처리와 그렇지 않을 때의 처리, 즉 두 가지 처리문 중에서 한개를 선택해야 할 때 사용

IF 조건문 THEN
	조건처리1;
ELSE
	조건처리2;
END IF;

 

DECLARE
    --%ROWRYPE 속성으로 로우를 저장할 수 있는 레퍼런스 변수 선언
    VEMPLOYEES EMPLOYEES%ROWTYPE;
    VSALARY NUMBER(8,2);
BEGIN
    DBMS_OUTPUT.PUT_LINE('사번 / 이름 / 급여');
    DBMS_OUTPUT.PUT_LINE('---------------------------------------');
    --Jack 사원의 전체 정보를 로우 단위로 얻어와 VEMPLOYEES에 저장
    SELECT * INTO VEMPLOYEES
    FROM EMPLOYEES
    WHERE FIRST_NAME ='Jack';
    --커미션이 NULL일 경우 급여만
    IF (VEMPLOYEES.COMMISSION_PCT IS NULL) THEN --커미션이 NULL이면
        VSALARY := VEMPLOYEES.SALARY;
    ELSE    --커미션이 NULL이 아니면 급여+수당
        VSALARY := VEMPLOYEES.SALARY + (VEMPLOYEES.SALARY * VEMPLOYEES.COMMISSION_PCT);
    END IF;
    
    --레퍼런스 변수와 스칼라 변수에 저장된 값을 출력
    DBMS_OUTPUT.PUT_LINE('사원번호 : ' ||VEMPLOYEES.EMPLOYEE_ID ||
                        ' / 사원명 : ' || VEMPLOYEES.FIRST_NAME ||
                        ' / 급여 : ' || TO_CHAR(VSALARY, '$999,999'));
END;
/

 

3] IF ~ THEN ~ ELSIF ~ ELSE ~ END IF: 여러 개 조건에 따라 처리도 여러 개일 때 사용하는 다중 IF

 

IF 조건문1 THEN
	조건처리 1;
ELSIF 조건문2 THEN
	조건처리 2;
ELSIF 조건문3 THEN
	조건처리 3;
ELSE
	조건처리N;
END IF;

 

DBMS RANDOM.VALUE

랜덤한 숫자를 생성

형식: DBMS_RANDOM.VALUE(최소 범위의 숫자, 최대 범위의 숫자)

 

--소수점 3번 째 자리까지 나타냄
SELECT ROUND(DBMS_RANDOM.VALUE(1,5),3) FROM DUAL;

SELECT ROUND(DBMS_RANDOM.VALUE(10,270),-1) FROM DUAL;

 

DBMS_RANDOM.STRING

랜덤한 문자열 생성

형식: DBMS_RANDOM.STRING(옵션문자, 길이수)

 

-옵션문자

'u','U': 대문자 , 'l','L': 소문자 , 'a', 'A': 대소문자 구분없는 영문자 ,'x', 'X': 영문자와 숫자 혼합 , 'p', 'P': 문자 혼합

 

DECLARE
    VSALARY NUMBER := 0;
    VDEPARTMENT_ID NUMBER := 0;
BEGIN
    SELECT ROUND(DBMS_RANDOM.VALUE(10, 270), -1) INTO VDEPARTMENT_ID FROM DUAL;
    --랜덤 숫자가 출력됨.
    
    SELECT SALARY INTO VSALARY
    FROM EMPLOYEES
    WHERE DEPARTMENT_ID = VDEPARTMENT_ID AND ROWNUM =1;
    
    DBMS_OUTPUT.PUT_LINE('부서번호: '|| VDEPARTMENT_ID ||' 급여 : ' ||VSALARY);
    
    IF VSALARY BETWEEN 1 AND 6000 THEN
        DBMS_OUTPUT.PUT_LINE('낮음');
    ELSIF VSALARY BETWEEN 6001 AND 10000 THEN
        DBMS_OUTPUT.PUT_LINE('중간');
    ELSIF VSALARY BETWEEN 10001 AND 20000 THEN
        DBMS_OUTPUT.PUT_LINE('높음');
    ELSE
        DBMS_OUTPUT.PUT_LINE('최상위');
    END IF;
EXCEPTION
    WHEN NO_DATA_FOUND THEN		--데이터 발견, 존재 X
    DBMS_OUTPUT.PUT_LINE(VDEPARTMENT_ID || '부서에 해당 사원이 없습니다.');
END;
/

 


JDBC(Java DataBase Connectivity): java.sql, javax.sql로 구성

자바 프로그램에서 데이터베이스와 연결하여 데이터베이스 관련 작업을 할 수 있게 해주는 API, 다양한 종류의 관계형 데이터베이스에 접근할 때 사용되는 자바 표준 SQL 인터페이스

 

JDBC는 다음과 같은 데이터베이스 기능을 지원하기 위한 표준 API를 제공

  • 데이터베이스를 연결하여 테이블 형태의 자료를 참조
  • SQL 문을 질의
  • SQL 문의 결과를 처리

각 DBMS와 관령하여 회사도 많고 그로 인해 사용하는 방법이 달라지면 X >> 이러한 문제를 해결하기 위해 SUN은 표준이 되는 인터페이스 제공

 

데이터베이스를 만드는 회사는 SUN사에서 JDBC인터페이스를 통해서 자신들의 데이터베이스에 맞게 기능들을 구현하는 것, 인터페이스만 알면 데이터베이스 조작 가능

 

JDBC드라이버(자료): 데이터베이스 회사들이 SUN사의 표준이 되는 인터페이스를 상속받아 구현해 놓은 것, 해당 DBMS에서 JDBC 관련 API 호출이 가능하도록 관련 인터페이스와 클래스를 구현한 클래스 라이브러리

JDBC는 SQL문을 DBMS에 전달하고 결과 셋을 반환해 주는 중개자 역할을 담당, 결과로 받은 데이터를 자바에서 사용할 수 있는 형태로 변환하여 프로그램에 반환

DBMS: 질의문을 컴파일하여 요청한 작업을 처리

java-컴파일->.class -->배표시 class 파일만 압축파일: .jar

 

JDBC: 자바에서 데이터베이스에 접근할 수 있게 해주는 PROGRAMMING API

THIN DRIVER: 확장, 배포 용이 WEB 적합

 

데이터베이스 인터페이스 사용하기 위해

프로젝트 우클릭, properties, javabuild path, add external jars

 

관계형 데이터베이스는 데이터를 여러 개의 테이블에 나누어서 저장

결과 집합(ResultSet): 쿼리의 조건을 만족하는 레코드들의 집합

커서(cursor): 특정 SQL 문장을 처리한 결과를 담고 있는 영역을 가리키는 일종의 포인터

 

JDBC를 이용하여 데이터베이스에 데이터를 액세스하기 위해서는 기본적인 순서

1.java.sql.*;

JDBC API를 사용하기 위해서는 반드시 선언

2.JDBC 드라이버 로딩 및 레지스터 등록

Class.forName() 사용

3.데이터베이스 연결(Connection 객체 얻는다.)

DriverManager.getConnnection() 사용

4.SQL을 위한 Statement 객체 생성

Connection.createStatement() 사용

5.SQL 실행

executeQuery() / executeUpdate()/ execute() 사용

6.ResultSet 결과셋 얻기

SQL문의 실행 결과셋 얻기.ResultSet에 저장된 데이터 값 추력

7.객체 자원 반납(연결 해제)

close() 사용

 

예외처리

-비체크 예외(runtime, nullpoint,...exception)

-체크 예외(반드시 예외처리) : 입출력

1.파일 입출력

2.네트워크 입출력

3.데이터베이스 입출력

 

JDBC관련 기본 클래스

패키지 인터페이스(클래스) 클래스 용도 이용 메소드
java.lang 클래스
Class
지정된 JDBC 드라이버를 실행시간동안 메모리에 로드 forName();
java.sql 클래스
DriverManager
여러 JDBC 드라이버를 관리하는 클래스로 데이터베이스를 접속하여 연결 객체 반환 getConnection();
인터페이스
Connection
특정한 데이터베이스 연결 상태를 표현하는 클래스로 질의할 문장 객체 반환 createStatement();
close();
인터페이스
Statement
데이터베이스에 SQL 질의 문장을 질의하여 그 결과집합 객체를 반환 executeQuery();
close();
인터페이스
ResultSet
질의 결과의 자료를 저장하며 테이블 구조 next(); getString(); getInt();
close();

 

데이터베이스에 연결하기 위해서는 2가지 과정이 필요하다.

가장 먼저 드라이버 클래스를 로딩, DB와 접속을 시도

 

DriverManager 클래스는 Class.forName() 메소드를 통해서 생성

드라이버 클래스들은 로드될 때 자신의 인스턴스(객체)를 생성하고, 자동적으로 DriverManager 클래스는 메소드를 호출하여 그 인스턴스를 등록

 

드라이버 클래스를 찾지 못할 경우 forName() 메소드는 ClassNotFoundException 예외를 발생시키므로 반드시 예외 처리

 

DriverManager: 데이터 원본에 JDBC드라이버를 통하여 커넥션을 만드는 역할, 데이터베이스 연결에 관한 책임을 가지고 있는 객체, Class.forName() 사용하고자 하는 JDBC 드라이버를 지정하여 해당 드라이버 내부에 있는 클래스들을 메모리에 로드하며 반드시 예외 처리를 해야함.

 

Connection: DB의 연결 정보를 담은 객체, 특정 데이터 원본과 연결된 커넥션을 나타낸다. 직접 객체 생성이 불가능하고 getConnection() 메소드를 사용하여 객체 생성 Statement 객체를 생성할 때도 Connection 객체를 사용하여 createStatement() 메소드를 호출하여 생성, SQL 문장을 실행시키기 전에 우선 Connection 객체가 있어야 함.

 

[형식 1]

1-1.Class.forName("드라이버 클래스명")

      Class.forName("oracle.jdbc.driver.OracleDriver") 또는

      Class.forName("oracle.jdbc.OracleDriver")

 

1-2.DriverManager.registerDriver(

                                new orcle.jdbc.driver.OracleDriver());

 

1-3. Connection conn = DriverManager.getConnection(

                                     "연결 url", "사용자명", "password");

 

 

JDBC 드라이버 로딩 & Connection 객체 생성

[형식 1]

Class.forName("oracle.jdbc.driver.OracleDriver"); 또는

Class.forName("oracle.jdbc.OracleDriver");

 

<javaproject 우클릭, properties, javabuilepath, classpath, ojdbc8.jar>

Statement

Connection 객체를 통해 DB에 SQL문을 전달하여 실행 시키고 결과 값을 반환받는 역할을 하는 객체

Connection 클래스의 createStatement() 메소드를 호출하여 얻어지며 생성된 Statement 객체로 질의 문장을 String객체에 담아 인자로 전달하여 executeQuery() 메소드를 호출하여 SQL질의 수행

 

executeUpdate(String sql) - SQL문이 insert, update, delete문 등일 경우

Statement stmt = conn.createStatement();

StringBuffer sb = new StringBuffer();
sb.append("UPDATE employees SET hire_date = sysdate ");
sb.append(" WHERE employee_id = 100");	//where절 앞에 공백
int updateCount = stmt.executeUpdate(sb.toString());

int executeUpdate(String sql) 사용시   //입력, 수정, 삭제

  • executeUpdate() 메소드의 매개변수의 자료형은 String이다.   //반환형 String
  • 문자열, 날짜형 데이터 싱클쿼테이변(')으로 표현해야 한다.
  • 데이터는 대소문자를 구분한다.

 

executeQuery(String sql) - SQL문이 select일 경우

Statement s = conn.createStatement();
String sql = "SELECT employee_id, first_name FROM employees";
ResultSet rs = s.executeQuery(sql);

Statement stmt = conn.createStatement();
StringBuffer sb = new StringBuffer();
sb.append("SELECT employee_id, first_name);
sb.append("FROM employees ");
ResultSet rs = stmt.executeQuery(sb.toString());

 

문자열 결합 연산자 +

-원본 문자열이 변경되지 않으니 문자열을 수정할 때마다 메모리에 새로운 문자열이 생성된고, 이전 문자열은 메모리에 남아 쓸데없는 자리만 차지하게 된다.

 

StringBuffer, StringBuilder

-StringBuffer 객체에 저장된 문자열은 수정할 수 있다.

-String 객체와 다르게 StringBuffer 객체는 +연산자를 통해 매번 새로운 String 객체를 생성하지 않고, append() 메서드를 통해 String 객체 하나만으로도 문자열을 다룰 수 있다.

-버퍼(buffer: 데이터를 임시로 저장하는 메모리)에 문자열 저장

-버퍼 내부에서 추가, 수정, 삭제 작업 가능

 

결과 집합(ResultSet)에서 레코드에 하나씩 접근하여서 작업을 하여야 한다. executeQuery() 메소드에 의하여 반환된 ResultSet 객체에는 SELECT문장에 의하여 추출된 모든 레코드가 들어 있다. 하지만 한 번에 하나의 레코드만 접근할 수 있다. 이것을 위하여 커서(특정 sql 문장을 처리한 결과를 담고 있는 영역을 가리키는 일종의 포인터 )라는 포인터가 제공되는데 이 커서를 움직이는 다양한 메소드가 제공

 

메소드 설명
close() 결과 집합은 닫는다.
first() 커서를 처음 레코드로 옮긴다.
last() 커서를 마지막 레코드로 옮긴다.
getRow() 현재 레코드 번호를 얻는다.
next() 다음 레코드로 이동한다.
previous() 이전 레코드로 이동한다.
absolute(int row) 지정된 row로 커서를 이동한다.
isFirst 첫 레코드이면 true 반환
isLast() 마지막 레코드이면 true 반환

 

메소드의 매개변수로 칼럼명으로 접근할 수 있고, 쿼리문 작성시 컬럼 순번으로 접근할 수 있다.

 

Statement stmt = conn.createStatement();
StringBuffer sb = new StringBuffer();
sb.append("SELECT employee_id, first_name ");
sb.append("FROM employees ");
ResultSet rs = stmt.executeQuery(sb.toString());

int empno = rs.getInt("employee_id");
String ename = rs.getString("first_name");

int empno = rs.getInt(1);
String ename = rs.getString(2);

 

자바에서는 인덱스 번호가 0부터 시작하지만 SQL에서는 1부터 시작한다.

결과 집합 처리 시 체크 사항

  • rs.next()를 맨 처음 한번 반드시 실행하여야 한다. 결과를 얻은 객체의 가장 처음 로우에 커서를 옮기는 작업으로 생각하면 된다. 만약 결과가 없다면 false를 리턴
  • ResultSet 객체에 next()를 호출함으로써 해당 객체는 getXXX() 메소드를 호출할 준비를 하게된다.
  • getInt(), getString(), getDate() 등 여러가지 데이터 형에 대한 메소드가 존재
  • 자바의 인덱스의 시작은 0부터이지만, 데이터베이스는 1부터 시작한다.

결과 집합에서 이동: 한 레코드씩 처리, 다음 행으로 이동시 next() 메소드를 사용

ResultSet 반환

BOF(Begin Of File, Before the First Row): 질의 결과 처음 커서 위치

EOF(End Of File, After the Last Row)

 

ResultSet: SELECT문을 사용한 질의 성공 시 ResultSet 반환

 

JDBC 코딩 절차

Driver 등록 - DBMS 연결 - Statement 생성 - SQL 전송 - 결과 받기 - 닫기(객체반환)

Statement method를 이용하여 SQL문 실행, 실행결과를 ResultSet(Select) 혹은 int형 변수(DML)로 받아서 처리

String query = "UPDATE subject SET s_name = '전기전자학과' WHERE s_num = '03'";
int result = stmt.executeUpdate(query);

 

'DataBase+SQL' 카테고리의 다른 글

PreparedStatement  (0) 2023.06.28
SQL 반복문, 커서  (0) 2023.06.27
MVIEW, 시퀀스  (0) 2023.06.23
뷰(VIEW)  (0) 2023.06.22
서브 쿼리  (0) 2023.06.21

View는 원본 테이블에 가서 데이터를 가져올 후 사용자에게 반환하기 때문에 부하가 많이 발생. (요청할 때 마다 접근)

 

11) Materialized View (MVIEW): 구체화된 뷰

Mview는 사용자가 요청하는 데이터를 가지고 있다가 요청이 들어오면 즉시 사용자에게 보내는 형태로 처리.

View는 데이터가 없기 때문에 실체가 없는 테이블이라고 하며 Mview는 데이터를 가지고 있기 때문에 "실체화된 View"라고 한다. => 사용자가 많고 데이터가 많을수록 Mview를 사용하는 것이 더 효율적이고 성능이 좋다.

 

Mview를 사용하기 위해 QUERY REWRITE라는 권한과 CREATE MATERIALIZED VIEW 권한이 필요

GRANT QUERY REWRITE TO HR;
GRANT CREATE MATERIALIZED VIEW TO HR;
--PDB_SYS로 권한 부여
--GRANT QUERY REWRITE TO HR;
--GRANT CREATE MATERIALIZED VIEW TO HR;

--MATERIALIZED VIEW(MVIEW): 구체화된 뷰 생성
CREATE MATERIALIZED VIEW M_EMP
BUILD IMMEDIATE --서브쿼리 부분을 수행해서 데이터를 가져오라는 의미
REFRESH
ON DEMAND --원본테이블 변경 시 동기화 여부 결정 사용자가 수동으로 동기화 명령을 수행해서 설정, 먼저 동기화를 쓰고 
--ON COMMIT 옵션은 원본 테이블에 데이터 변경 후 COMMIT이 발생하면 자동으로 동기화시키라는 의미.
COMPLETE --MVIEW 내의 데이터 전체가 원본 테이블과 동기화 되는 방법.
ENABLE QUERY REWRITE
AS
SELECT EMPLOYEE_ID, FIRST_NAME, SALARY FROM EMP01;

SELECT * FROM M_EMP;

DELETE FROM EMP01 WHERE EMPLOYEE_ID = 250;

SELECT COUNT(*) FROM EMP01; --107 : 데이터를 지워서 적어짐
SELECT COUNT(*) FROM M_EMP; --108 : 개수가 달라짐. 기존 테이블의 데이터로 존재
--DBMS_MVIEW 패키지의 REFRESH구문으로 동기화를 수행, 자동으로 동기화하지 않고 수동으로 동기화를 해서 한번에 적용
--BIGIN부터 END까지 BLOCK설정

BEGIN
    DBMS_MVIEW.REFRESH('M_EMP');
END;
/
--오라클에서는 패키지.프로시저명을 사용

SELECT COUNT(*) FROM M_EMP; --107 : 동기화됨.

--확인
SELECT MVIEW_NAME, QUERY FROM USER_MVIEWS
WHERE MVIEW_NAME = 'M_EMP';

DROP MATERIALIZED VIEW M_EMP;
--변경 시 ALTER 사용 X, 삭제하고 다시 CREATE

 

PARTITION BY

오라클에서 그룹함수를 사용할 때 PARTITION BY를 사용하여 그룹으로 묶어서 연산.

GROUP BY 를 사용하지 않고, 조회된 각 행에 그룹으로 집계된 값을 표시 할 때 OVER 절과 함께 PARITION BY절 사용

--부서 번호와 사원명, 부서별 급여의 합을 함께 출력.
SELECT DEPARTMENT_ID, FIRST_NAME,
SUM(SALARY) OVER (PARTITION BY DEPARTMENT_ID) AS SALARY_TOTAL
FROM EMPLOYEES
WHERE DEPARTMENT_ID BETWEEN 10 AND 30
ORDER BY DEPARTMENT_ID;

--그룹함수([칼럼]) OVER(PARTITION BY 칼럼1, 칼럼2,...[ORDER BY 절]..)

SELECT DEPARTMENT_ID, FIRST_NAME, SALARY,
        SUM(SALARY) OVER(PARTITION BY DEPARTMENT_ID) AS DEPARTMENT_TOTAL,
        SUM(SALARY) OVER() AS SALARY_TOTAL --10~30 SALARY들의 합
FROM EMPLOYEES
WHERE DEPARTMENT_ID BETWEEN 10 AND 30
ORDER BY DEPARTMENT_ID;
--각 부서에 소속된 사원 한명만을 출력, 이때 사원번호, 사원명, 직무번호, 급여, 부서번호
SELECT EMPLOYEE_ID, FIRST_NAME, DEPARTMENT_ID, HIRE_DATE
FROM(SELECT ROW_NUMBER() OVER(PARTITION BY DEPARTMENT_ID ORDER BY EMPLOYEE_ID) AS RNUM,
            EMPLOYEE_ID, FIRST_NAME, DEPARTMENT_ID, HIRE_DATE
            FROM EMPLOYEES) DATA
WHERE DATA.RNUM = 1;

시퀀스

레코드를 식별하기 위해 사용

PRIMARY KEY(중복 허용하지 않음)로 지정한 칼럼에 일련번호를 자동으로 부여받기 위해 시퀀스의 생성

 

(1) 시퀀스 생성: 유일(UNIQUE)한 값을 생성해주는 오라클 객체(=>CREATE), 기본키와 같이 순차적으로 증가하는 칼럼을 자동적으로 생성, 보통 테이블 당 하나의 시퀀스

중간이 비어도 채울필요X, 자동으로 MAX값의 다음 값

CREATE SEQUENCE SEQUENCE_NAME
	[START WITH N]
    [INCREMENT BY N]
    [{MAXVALUE N|NOMAXVALUE}]	--최대값//안잡으면 잡을 수 있는 값만큼
    [{MINVALUE N|NOMINVALUE}]	--최소값
    [{CYCLE|NOCYCLE}]			--최대 값까지 간 후에 다시 최소값부터 사용할 것인지
    [{CACHE N|NOCACHE}]

 

① START WITH: 시퀀스의 시작 값을 지정. N을 1로 지정하면 1부터 순차적으로 시퀀스 번호가 증가

② INCREMENT BY: 시퀀스의 증가 값. N을 2로 하면 2씩 증가. START WITH를 1로 하고 INCREMENT BY를 2로 하면 1,3,5,7로 시퀀스 번호가 증가

③MAXVALUE N|NOMAXVALUE: MAXVALUE는 시퀀스가 증가할 수 있는 최댓값을 말한다. NOMAXVALUE는 시퀀스의 값을 무한대로 지정

④MINVALUE N | NOMINVALUE: 시퀀스의 최솟값. 기본값 1, NOMINVALUE를 지정할 경우 최솟값은 무한 소

⑤CYCLE(사이클)|NOCYCLE: 시퀀스 값이 최댓값까지 증가가 완료되면 다시 최솟값에서부터 시퀀스를 시작하도록 하려면 CYCLE, NOCYCLE은 최댓값을 넘어서면 오류(디폴트 값: NOCYCLE)

⑥CACHE(캐쉬) N|NOCACHE: 오라클 서버가 미리 지정하고 메모리에 유지할 값의 수로 디폴트 값은 20, 값 들어갈때 같이 올라간다.

 

--테이블 생성
CREATE TABLE TEST(
    NO NUMBER NOT NULL PRIMARY KEY
);
--테이블 TEST에 사용할 시퀀스 TEST_SEQ 생성
CREATE SEQUENCE TEST_SEQ
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 100000
NOCYCLE
CACHE 2;	--최소값인 1보다 커야한다.
--DROP SEQUENCE TEST_SEQ;	--SEQUENCE는 DROP 다음 다시 CREATE로 수정

INSERT INTO TEST VALUES(TEST_SEQ.NEXTVAL);
--시퀀스를 사용하지 않았을 경우 자동증가하는 값으로 설정하기 위한 쿼리문
INSERT INTO TEST VALUES((SELECT MAX(NO)+1 FROM TEST));

SELECT * FROM TEST;

--시퀀스의 현재값 반환
SELECT TEST_SEQ.CURRVAL FROM DUAL;

--시퀀스의 현재값에서 증가한 값(+1) 반환
SELECT TEST_SEQ.NEXTVAL FROM DUAL;

 

'DataBase+SQL' 카테고리의 다른 글

SQL 반복문, 커서  (0) 2023.06.27
PL/SQL  (0) 2023.06.26
뷰(VIEW)  (0) 2023.06.22
서브 쿼리  (0) 2023.06.21
그룹 함수  (0) 2023.06.20

반복문 A+B -4를 풀 때 언제 종료를 해줘야 할 지 알 수 없어서 고민하던 중 질문 게시판에 나와 같은 고민을 하는 질문글을 보았다. 

EOF(End of File)이란?

더 이상 읽을 수 있는 데이터가 없음을 나타내는 용어로 알고리즘 문제를 풀 때는 주로 입력값을 얼마나 받을 지 명시하지 않을 경우 사용한다.

 

EOF의 사용법

1.Sanner 클래스: hasNext() 사용

=입력된 토큰이 있으면 true, 그렇지 않을 경우 false 반환

Scanner scan = new Scanner(System.in);
		
while(scan.hasNext()) {
  System.out.println(scan.nextLine());
}

while(scan.hasNext()) {
  sc.next();
}

 

2.BufferedReader 클래스 :내장 함수가 없다. StringTokenizer의 경우 문자열을 입력하는 것이 아닌 입력받은 문자열을 가송하는 역할로 EOF를 철리한다고 보기 어렵다.

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = "";

while((input = br.readLine()) != null) {
  // 이후 로직 전개.
}

while((input = br.readLine()) != null && !input.isEmpty()) { ... }

백준: 반복문 A+B -4

isEmpty(): 빈 문자열인지 확인=> 안 쓰면 JAVA에서 오류

package practice;
import java.util.*;
import java.io.*;
public class Main {
	public static void main(String args[]) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		String s;
		
		while((s = br.readLine())!=null) {
			StringTokenizer st= new StringTokenizer(s);
			if(s.isEmpty()) break;
            
			int A = Integer.parseInt(st.nextToken());
			int B = Integer.parseInt(st.nextToken());
			bw.write((A+B)+"\n");		
		}
		bw.flush();
	}
}

+ Recent posts