728x90

 

finally 블록을 추가하면 try문에서 return을 해도 무조건 실행된다!

public class Ex4 {

	public static void main(String[] args) {
		try {
			inputScore(101);
		} catch (InvalidScoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// throws로 예외처리의 책임을 상위로 위임함
	public static void inputScore(int score) throws InvalidScoreException {

		if (score < 0 || score > 100) {
        	// 사용자정의 예외클래스로 예외 발생
			throw new InvalidScoreException("0 ~ 100사이의 정수만 입력하셈");
		}
	}

}

// Exception(상위 예외클래스)를 상속하는 사용자정의 예외클래스
class InvalidScoreException extends Exception {

	public InvalidScoreException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

}
728x90

이클립스에서 웹 프로젝트 시 Unable to compile class for JSP: 나

java.lang.ClassNotFoundException 오류가 뜰 때가 있다.

 

[해결법]

첫번째 방법

Project - Clean 

 

두번째 방법

Project - Properties - Java Build Path - Order and Export - JRE System Library 에 체크 후 Apply

 

세번째 방법

Project - Build Automatically 가 체크해제 되어있으면 체크

'Study > Java' 카테고리의 다른 글

[JAVA] 예외처리와 사용자 정의 예외 클래스  (0) 2021.04.02
[JAVA] 추상(abstract)  (0) 2021.03.09
[JAVA] final 키워드 / 상수(constant)  (0) 2021.03.09
[JAVA] 다형성 / 다이나믹 바인딩  (0) 2021.03.08
JAVA - getter, setter  (0) 2021.02.09
728x90

DDL (데이터 정의 언어 : Data Define Language)

Schema, Domain,Table, View, Index를 정의하거나 변경 또는 삭제할 때 사용하는 언어

 

DDL 유형

CREATE, ALTER, DROP...

 

[ CREATE ]

1. 테이블 생성 

SQL > CREATE TABLE TBL_PANAME
	(PDCODE     VARCHAR2(10),
	PANDAY      DATE DEFAULT SYSDATE,
	PANSU        NUMBER,
	CONSTRAINT TBL_PANAME_PDCODE_FK --- 테이블 레벨의 제약조건
                    FOREIGN KEY(PDCODE)
                    REFERENCES TBL_PRODUCT(PDCODE)
                    ON DELETE CASCADE );

* CREATE, SELECT, FROM 등을 '키워드' 또는 '예약어'라고 한다

키워드 + 요소를 ---절이라고 한다. ( 예: SELECT + 요소 -> SELECT 절)

 

2. 제약조건

컬럼레벨의 제약조건은 , 없이 뒤에 이어서 CONSTRAINT문법을 적음

테이블 레벨의 제약조건은 컬럼 정의가 끝나고 (, 로 종결) 추가

 

제약조건 명명규칙은 테이블이름(약식)_컬럼명_제약조건종류

* [constraint 제약조건명] 생략가능 
다만 관리가 어렵기때문에 권장하지 않음

 

1) NOT NULL 제약 조건 - 컬럼 레벨의 문법만 가능

SQL> create table test1
	( id number(10) constraint t1_id_nn not null,
    	name varchar2(30) constraint t1_name_nn not null,
        job varchar2(20),
        email varchar2(20),
        phone varchar2(20) constraint t1_ph_nn not null,
        start_date date );

2) UNIQUE 제약조건

중복값 허용 안함

SQL> create table test2
	(id number(10) constraint t2_id_nn not null,
    				constraint t2_id_uk unique,	---comlumn-level constraint
                    (...)                  
    email varchar2(20),
	start_date date,
    constraint t2_email_uk unique(email) ); --- table-level constraint

3) PRIMARY KEY 제약조건

- NOT NULL + UNIQUE 의 성격을 가짐

- 테이블의 대표 컬럼에 적용하는 제약조건 (구별을 할 수 있는 키)

- 주민번호같이 민감한 정보에는 사용하지 않는다.

SQL> CREATE TABLE test3
  2  (id number(10) constraint t3_id_pk primary key,
  3  name varchar2(30) constraint t3_name_nn not null,
  4  job varchar2(20),
  5  email varchar2(20),
  6  phone varchar2(20) constraint t3_ph_nn not null
  7                     constraint t3_ph_uk unique,
  8  start_date DATE,
  9  constraint t3_email_uk UNIQUE(email));

Table created.

4) FOREIGN_KEY 제약조건

자기 자신 테이블이나 다른 테이블 특정칼럼(PK, UK)을 참조하는 제약조건

* 예) 없는 부서 아이디(department_id)를 사원정보(employees)에 입력해선 안된다.

 

4-1) 테이블레벨 제약조건

employess.department_id 컬럼에 제약조건을 걸되, 참조하는 컬럼은 departments.department_id

CREATE TABLE employess (
	employee_id	NUMBER(6),
	last_name	VARCHAR2(25) NOT NULL,
	email		VARCHAR2(25),
	salary		NUMBER(8,2),
	commission_pet	NUMBER(2,2),
	hire_date		DATE NOT NULL,
(...)
	department_id	NUMBER(4),
	CONSTRAINT emp_dept_fk FOREIGN KEY (department_id)
		REFERENCES departments(department_id),
	CONSTRAINT emp_email_uk	Unique(email) );

4-2) 컬럼레벨 제약조건

* REFERENCES 절이 있으므로 컬럼레벨에선 제약조건종류(FOREIGN KEY) 키워드를 적지 않는다.

CREATE TABLE employess 
(
	(...)	
	department_id	NUMBER(4) CONSTRAINT emp_dept_fk
		REFERENCES departments(department_id),
    (...)
)

4-3) 자기 자신 컬럼을 참조하는 제약조건

ex) 매니저 아이디는 반드시 사원정보 테이블의 사원ID(employee_id)에 존재하는 값이어야 함

CREATE TABLE employess 
(
	(...)	
	manager_id	NUMBER(6)
    	CONSTRAINT emp_manager_fk REFERENCES
        employee (employee_id)
    (...)
)

 

5) CHECK 제약조건

(...)
	salary NUMBER(2)
    CONSTRAINT emp_salary_min
    	CHECK (salary > 0)	--- salary의 값이 0 이상이어야 함
(...)        

 

3. 제약조건 조회 (데이터 딕셔너리)

(* 테이블 이름은 DB에 저장될 때 무조건 대문자로 저장되기 때문에 조회 시 대문자로 적는다)

SELECT constraint_name, constraint_type, search_condition
       FROM USER_CONSTRAINTS
       WHERE TABLE_NAME = '<테이블이름>';

 

4. 서브쿼리 구문으로 테이블 생성

CREATE TABLE <테이블명>
 AS
  SELECT
  FROM
  WHERE

예) 서브쿼리로 테이블 생성하되, WHERE절 조건에 맞는 VALUES도 가져오기

 

CREATE TABLE dept80
    AS
        SELECT employee_id, last_name, salary*12 ANNSAL, hire_date
          FROM employees
          WHERE department_id = 80;

SELECT결과

EMPLOYEE_ID LAST_NAME                     ANNSAL HIRE_DAT
----------- ------------------------- ---------- --------
        145 Russell                       168000 04/10/01
        146 Partners                      162000 05/01/05
        147 Errazuriz                     144000 05/03/10
        148 Cambrault                     132000 07/10/15
        149 Zlotkey                       126000 08/01/29
        150 Tucker                        120000 05/01/30
        151 Bernstein                     114000 05/03/24
        152 Hall                          108000 05/08/20
        153 Olsen                          96000 06/03/30
        154 Cambrault                      90000 06/12/09
        155 Tuvault                        84000 07/11/23

제약조건 조회결과

SELECT constraint_name, constraint_type, search_condition, r_constraint_name
FROM user_constraints
WHERE table_name = 'DEPT80';

* 제약조건은 NOT NULL 외에 복사되지 않으며 NOT NULL도 제약조건명은 임의로 붙여진다.

CONSTRAINT_NAME            C SEARCH_CONDITION             R_CONSTRAINT_NAME                  
-------------------------------------------------------------------------------
SYS_C007745                C "LAST_NAME" IS NOT NULL       NULL
SYS_C007746                C "HIRE_DATE" IS NOT NULL       NULL

 

예) 서브쿼리로 테이블 생성 시 구조만 가져오기

* WHERE절에 항상 false가 되는 조건을 넣으면 된다.

CREATE TABLE dept80_2
    AS
        SELECT employee_id, last_name, salary * 12 annsal, hire_date
        FROM employees
        WHERE 1 = 2;

5. 테이블 생성 시 대소문자 구분 또는 띄어쓰기 사용하여 생성

소문자 이름 (큰 따옴표 사용)으로 테이블을 특별히 생성하지 않은 경우 테이블 이름은 기본적으로 대문자로 설정된다.

 

1) 대소문자 구분

CREATE TABLE "myTest" (id CHAR(10)); 

2) 대소문자 구분 및 띄어쓰기

CREATE TABLE "my Test" (id CHAR(10)); 

 

위와 같이 ""안에 테이블명을 입력할 경우 대소문자가 구분되고, 띄어쓰기를 사용할 수 있게 된다.

 

 

[ ALTER ]

1. 테이블 수정

1) 테이블에 컬럼 추가

ALTER TABLE dept80
ADD	(job_id VARCHAR2(0) ); -- job_id컬럼추가

2) 테이블 기존 컬럼 삭제

ALTER TABLE dept80
MODIFY	(last_name VARCHAR2(30) ); -- 데이터타입,컬럼사이즈,기본값 등

3) 테이블 기존 컬럼에 제약조건 추가

ALTER TABLE emp2
ADD CONSTRAINT emp_mgr_fk			---emp_mgr_fk 이름으로 제약조건 추가
	FOREIGN KEY(manager_id)			-- manager_id컬럼을 외래키로 지정
    REFERENCES emp2(employee_id);	-- emp2테이블의 employee_id컬럼 참조

4) 테이블 제약조건 삭제

ALTER TABLE emp2
DROP	CONSTRAINT emp_mgr_fk;	---emp_mgr_fk이란 이름의 제약조건 삭제

 

[ DROP ]

1. 테이블 삭제

1) 테이블 삭제

1-1) 휴지통을 거치고 삭제

DROP TABLE emp2;

 

1-2) 휴지통을 거치지 않고 삭제 (PURGE키워드 추가)

DROP TABLE emp2 PURGE;

[ FLASHBACK ]

2) 플래쉬백 테이블

실수로 삭제 시 recyclebin으로부터 복원

 

2-1) 휴지통에서 기존이름, 마지막 동작, 삭제 시간 조회

SELECT original_name, operation, droptime FROM
recyclebin;

select * from tab; 으로 테이블을 조회했을 때 아래와 같이 이상한 이름의 테이블명이 보일 것이다. 이는 휴지통에 들어가있는 테이블을 뜻한다. 휴지통의 가용용량은 DB마다 설정마다 다를 수 있다.

BIN$veCJQvVBOgTgVbkzEzPhBQ==$0 
BIN$vj9KzAO5DMjgVbkzEzPhBQ==$0 
BIN$vj9KzAO9DMjgVbkzEzPhBQ==$0 

 

2-2) 복구

FLASHBACK TABLE emp2 TO BEFORE DROP;

[ TRUNCATE ]

1. 테이블 절단 (TRUNCATE)

- 테이블 구조는 남기고 모든 행 제거

* DDL구문이므로 ROLLBACK 불가

TRUNCATE TABLE <테이블이름>;

* DELETE 문과 차이

- DELETE는 테이블의 특정 행 삭제 또는 WHERE절 생략 시 모든 행 삭제

- DELETE는 DML(데이터 조작어)이나 TRUNCATE는 DDL(데이터 정의어)

- DELETE는 저장공간은 그대로이나 TRUNCATE는 저장공간 제거

- DELETE는 ROLLBACK이 가능하나  TRUNCATE는 ROLLBACK

 

* 프로그래머가 테이블 객체 자체는 필요하나 공간을 지우고 더 이상 새 데이터를 삽입할 필요없을 때 쓸 수 있다.

 

[ VIEW ]

뷰는 하나 이상의 Base table로 생성되나 물리적으로 존재하는 것은 아니다.

SELECT 구문형태로 정의만 되어있는 가상 논리적 테이블을 말한다.

 

  • 뷰의 장점
    - 특정 사용자에게 필요한 필드만 제공가능
    - 복잡한 쿼리 단순화
    - 쿼리 재사용 
  • 뷰의 단점
    - 한 번 정의된 뷰는 변경 불가
    - 삽입, 삭제, 갱신 작업에 제한 있음
    - 자신만의 인덱스를 가질 수 없음

1. 뷰 생성

1) 서브 쿼리 이용 

CREATE VIEW empvu80 AS
    SELECT employee_id, last_name, salary
    FROM employees
    WHERE department_id = 80;

구조 보기

desc empvu80;
이름          널?       유형           
----------- -------- ------------ 
EMPLOYEE_ID NOT NULL NUMBER(6)    
LAST_NAME   NOT NULL VARCHAR2(25) 
SALARY               NUMBER(8,2)  

2) 서브쿼리에 AS키워드 이용

CREATE VIEW salvu50 AS
    SELECT employee_id  id_number, 
    		last_name    name, 
            salary * 12    ann_salary
    FROM employees
    WHERE department_id = 50;

데이터 조회

select * from salvu50;
 ID_NUMBER NAME                      ANN_SALARY
---------- ------------------------- ----------
       120 Weiss                          96000
       121 Fripp                          98400
       122 Kaufling                       94800
  • 표현식이나 함수를 사용한 컬럼은 AS키워드 이용한 컬럼 앨리어스가 필요함.

 

2. 뷰 수정 (OR REPLACE)

VIEW의 생성구문에 OR REPLACE 키워드를 사용하는 경우 동일한 이름의 뷰가 없다면 그대로 생성되고 동일한 이름을 사용하는 뷰가 있다면 새롭게 정의하는 뷰의 내용으로 대체하는 동작을 하게된다.

 

1) AS 사용 (base table이 하나인 simple view)

  • 뷰에서 앨리어스 리스트를 작성한 경우 서브쿼리의 컬럼명보다 우선적으로 적용되어 뷰의 컬럼명으로 사용된다.
CREATE OR REPLACE VIEW empvu80 (
    id_number, name, sal, department_id
) AS
    SELECT employee_id, 
              first_name || ' ' || last_name, 
              salary, department_id
    FROM employees
    WHERE department_id = 80;

조회

ID_NUMBER NAME                                                  SAL DEPARTMENT_ID
---------- ---------------------------------------------- ---------- -------------
       145 John Russell                                        14000            80
       146 Karen Partners                                      13500            80
       147 Alberto Errazuriz                                   12000            80

2) JOIN, 함수 사용 (base table이 하나 이상인 complex view)

CREATE OR REPLACE VIEW dept_sum_vu (
    name, minsal, maxsal, avgsal
) AS
    SELECT d.department_name, MIN(e.salary), MAX(e.salary), AVG(e.salary)
    FROM employees e
    JOIN departments d ON ( e.department_id = d.department_id )
    GROUP BY d.department_name;

조회

NAME                               MINSAL     MAXSAL     AVGSAL
------------------------------ ---------- ---------- ----------
Administration                       4400       4400       4400
Accounting                           8300      12008      10154
Purchasing                           2500      11000       4150

3. 뷰 사용

select salary from employees where employee_id = 145;
    SALARY
----------
     14000

update 후 조회

UPDATE empvu80
SET
    sal = sal + 500
WHERE id_number = 145;
    SALARY
----------
     14500

insert 시 다음과 같이 제약이 따른다.

INSERT INTO empvu80 (
    employee_id, last_name, salary
) VALUES (
    80, 'test', 8000
);

NOT NULL컬럼이 있지만 해당 컬럼의 정보를 가진 뷰를 가지고 있지 않아 삽입할 수 없다.

명령의 99 행에서 시작하는 중 오류 발생 -
insert into empvu80 (employee_id, last_name, salary)
values (80, 'test', 8000)
오류 보고 -
ORA-01400: NULL을 ("HR"."EMPLOYEES"."EMAIL") 안에 삽입할 수 없습니다

4. 뷰 삭제

DROP VIEW empvu80;

 

[ SEQUENCE ]

자동으로 고유 번호를 반환하는 오브젝트

 

1. 시퀀스 생성

CREATE SEQUENCE dept_deptid_seq2 
INCREMENT BY 10
START WITH 120 
MAXVALUE 9999 
NOCACHE 
NOCYCLE;

옵션

  • INCREMENT BY 생성할 숫자의 증감 간격을 설정하는 옵션절
  • START WITH 숫자 생성을 시작할 값을 설정
  • MAXVALUE 최대값 지정
    NOMAXVALUE 최대값 지정하지 않음 10^27
  • MINVALUE 최소값 지정
    NOMINVALUE 최소값 지정하지 않음 -(10^26)
  • CYCLE 최대|최소값 도달 시 초기화
    NOCYCLE 한계값 도달 시 멈춤

CACHE 미리 지정된 개수의 값을 생성 기본값
NOCACHE 값을 미리 생성하지 않음. 권장하지 않음

 

2. 시퀀스 사용

아래 쿼리 조회 시 INCREMENT BY만큼 증가한다.

select dept_deptid_seq.nextval
from dual;

INSERT 활용

INSERT INTO departments (
    department_id, department_name
) VALUES (
    dept_deptid_seq.NEXTVAL, 'LAST'
);

alter sequence

  • start with 를 제외한 나머지 옵션은 수정 가능

 

'DB' 카테고리의 다른 글

[오라클 DB] 일반 함수/그룹함수  (0) 2021.03.10
[오라클 DB] 함수-숫자  (0) 2021.03.10
[오라클 DB] 함수-문자)  (0) 2021.02.26
[오라클 DB] DQL 심화학습  (0) 2021.02.19
[오라클 DB] 온라인에서 Oracle SQL 테스트하기  (0) 2021.02.19
728x90

NVL

  • 컬럼의 NULL 값을 실제값으로 대체해서 출력해주는 함수

  • NULL값이 아닌 행은 원래 값을 출력하고 NULL을 가진 행에서만 대체값으로 결과를 출력한다.

  • 기존의 데이터와 NULL의 대체값이 같은 행에 출력되기 때문에 대체값도 컬럼의 데이터 타입과 동일해야한다.

SQL> SELECT commission_pct, NVL(commission_pct, 0)
  2  FROM employees;
(...)
COMMISSION_PCT NVL(COMMISSION_PCT,0)
-------------- ---------------------
            .2                    .2
           .15                   .15
            .1                    .1
                                   0
                                   0
(...)

NVL2

  • NULL값의 여부에 따라 간접적으로 결과를 연산하는 함수

  • NVL2(NULL여부를 판단할 컬럼, NULL값이 아닌경우 출력값, NULL값인 경우 출력값)

  • 2,3번째 인자가 값이 함수의 출력 결과가 되므로 데이터 타입이 통일되어야 한다.

 

NULLIF

만약(if) 첫번째 인자와 두번째 인자값을 비교해서 같으면 NULL, 다르면 첫번째인자값을 출력하는 함수

SQL> select first_name, length(first_name) "expr1", 
  2  last_name, LENGTH(last_name) "expr2", 
  3  nullif(length(first_name), length(last_name)) result 
  4  from employees; 

FIRST_NAME   expr1 LAST_NAME        expr2  RESULT 
-------------------- ---------- ------------------------- ---------- ---------- 
Ellen       5 Abel    4       5 
Sundar       6 Ande    4       6 
Mozhe       5 Atkinson    8       5 

 

COALESCE

  • 여러 대체값을 줄 수 있는 함수.

  • NULL값이 아닌 첫 대체값이 출력된다.

즉 널이 아닌 값을 찾아 출력하는 식이다. ( a가 널이고 b가 널이면 널이아닌 c출력)

SQL> SELECT last_name, employee_id,
  2  COALESCE(TO_CHAR(commission_pct), TO_CHAR(manager_id), 'No commission and No manager')
  3  FROM employees;


LAST_NAME                 EMPLOYEE_ID COALESCE(TO_CHAR(COMMISSION_PCT),TO_CHAR
------------------------- ----------- ----------------------------------------
King                              100 No commission and No manager
Kochhar                           101 100
De Haan                           102 100
Hunold                            103 102
Ernst                             104 103
Austin                            105 103
(...)

사장(king)은 커미션과 매니저 아이디가 없어서 마지막 인자의 값이 출력된 걸 알 수 있다.

 

 

ex) 사원들 이름과 커미션을 출력하되, 커미션 없는 사람은 No Commission출력하기

NVL 함수 이용

SQL> select last_name, nvl(to_char(commission_pct), 'No Commission')
  2  from employees;
(...)
LAST_NAME		  COMM
------------------------- ----------------------------------------
Livingston		  .2
Grant			  .15
Johnson 		  .1
Taylor			  No Commission
Fleaur			  No Commission
Sullivan		  No Commission
(...)

COALESCE 함수 이용

  1  select last_name,
  2  coalesce(to_char(commission_pct), 'No Commission') COMM
  3* from employees

 

 

그룹 함수(여러 행 함수)

  • 그룹 단위로 연산하는 함수

  • GROUP BY절을 통해서 그룹을 나누지 않았다면 테이블의 행 전체가 하나의 그룹

  • 그룹 함수는 연산에서 NULL값을 제외하고 연산한 결과를 출력


숫자 데이터 입력 함수

AVG([DISTINCT|ALL] n) 평균

STDDEV([DISTINCT|ALL] n) 표준편차

VARIANCE([DISTINCT|ALL] n) 분산

SUM([DISTINCT|ALL] n) 합계

 

___ : 기본 옵션

 

ex) 월급의 각 항목별 연산

SQL> SELECT AVG(salary), STDDEV(salary), VARIANCE(salary), SUM(salary)
  2  FROM employees;


AVG(SALARY) STDDEV(SALARY) VARIANCE(SALARY) SUM(SALARY)
----------- -------------- ---------------- -----------
 6461.83178     3909.57973       15284813.7      691416

ex) distinct로 중복제외한 연산

SQL> select avg(distinct salary), avg(salary) from employees;

AVG(DISTINCTSALARY) AVG(SALARY)
------------------- -----------
	 7067.37931  6461.83178

 

모든 데이터를 연산하는 함수

COUNT(*|[DISTINCT|ALL] expr) 행 개수 카운트

MAX([DISTINCT|ALL] expr) 최대값

MIN([DISTINCT|ALL] expr) 최소값

 

ex) 커미션을 받는 사원이 35명뿐이기 때문에(null값이 아닌 레코드) salary의 count와 값이 다름을 알 수 있다.

SQL> select count(*) from employees;

  COUNT(*)
----------
       107
SQL> select count(salary), max(salary), min(salary) from employees;

COUNT(SALARY) MAX(SALARY) MIN(SALARY)
------------- ----------- -----------
	  107	    24000	 2100

SQL> select count(commission_pct), max(hire_date), min(employee_id) from employees;

COUNT(COMMISSION_PCT) MAX(HIRE_ MIN(EMPLOYEE_ID)
--------------------- --------- ----------------
		   35 21-APR-08 	     100

 

GROUP BY 절 결합

ex) 그룹별 카운트

 

  1  select department_id, COUNT(*), AVG(SALARY)
  2  from employees
  3* group by department_id

DEPARTMENT_ID	COUNT(*) AVG(SALARY)
------------- ---------- -----------
	  100	       6  8601.33333
	   30	       6	4150
       (...)

 

'DB' 카테고리의 다른 글

[오라클DB] DDL  (0) 2021.03.24
[오라클 DB] 함수-숫자  (0) 2021.03.10
[오라클 DB] 함수-문자)  (0) 2021.02.26
[오라클 DB] DQL 심화학습  (0) 2021.02.19
[오라클 DB] 온라인에서 Oracle SQL 테스트하기  (0) 2021.02.19
728x90

[숫자함수]

ROUND : 반올림

TRUNC : 버림

MOD : 나머지

 

예) 숫자 함수와 표현식 응용

1600/300으로 표현식을 쓰면 정수가 아닌 5.33333333의 결과가 출력된다. 이 때는 TRUNC를 통해 소수점을 버릴 수 있다.

SQL> select round(45.926, 2), trunc(45.926, 2), mod(1600, 300), trunc(1600/300, 0)
  2  from dual;

ROUND(45.926,2) TRUNC(45.926,2) MOD(1600,300) TRUNC(1600/300,0)
--------------- --------------- ------------- -----------------
	  45.93 	  45.92 	  100		      5

예) ROUND함수에 0이하의 숫자를 두번째 인자에 써서 반올림할 수도 있다.

아래 45에서 일의 자리가 0, 십의 자리가 -1 이며 이 이하의 값 (에 : -2)을 지정하면 결과값이 0으로 출력된다.

SQL> select round(45.926, -1)
  2  from dual;

ROUND(45.926,-1)
----------------
	      50

SQL> select round(45.926, 0)
  2  from dual;

ROUND(45.926,0)
---------------
	     46
         
SQL> select round(45.926, -2) from dual;

ROUND(45.926,-2)
----------------
	       0

두번째 인자를 생략하면  (    ,  0 ) 으로 지정한 것과 같다.

 

 

예) 인상급여와 증가분을 구하는 예제 (소수점 첫째자리 반올림)

SQL> select employee_id, last_name, salary,
  2  round (salary*1.155) "New Salary",
  3  round (salary*1.155 - salary) Increase
  4  from employees;

EMPLOYEE_ID LAST_NAME			  SALARY New Salary   INCREASE
----------- ------------------------- ---------- ---------- ----------
	100 King			   24000      27720	  3720
	101 Kochhar			   17000      19635	  2635
	102 De Haan			   17000      19635	  2635
	103 Hunold			    9000      10395	  1395
	104 Ernst			    6000       6930	   930
	105 Austin			    4800       5544	   744
	106 Pataballa			    4800       5544	   744

 

 

SQL> select to_number('24,900.55', '99,999.99') from dual;

TO_NUMBER('24,900.55','99,999.99')
----------------------------------
  24900.55

'DB' 카테고리의 다른 글

[오라클DB] DDL  (0) 2021.03.24
[오라클 DB] 일반 함수/그룹함수  (0) 2021.03.10
[오라클 DB] 함수-문자)  (0) 2021.02.26
[오라클 DB] DQL 심화학습  (0) 2021.02.19
[오라클 DB] 온라인에서 Oracle SQL 테스트하기  (0) 2021.02.19
728x90

추상(abstract)

추상(abstract)는 공통적인 특성을 정의하여 구체적인 부분은 자식클래스에서 정의하도록 하는 것이다.

이때 공통되는 특성을 가진 상위클래스를 추상 클래스, 이를 상속해 구체화하는 서브클래스는 실체화 클래스라고도 한다.

 

추상 클래스

추상 클래스는 new를 하지 못한다. (인스턴스 생성불가)

추상클래스는 멤버변수, 생성자, 일반메서드, 추상메서드를 가질 수 있다.

public class Ex3 {
	public static void main(String[] args) {
    	// Cannot instantiate the type AbstractClass
//		AbstractClass abstractClass = new AbstractClass();
	}
}

 

추상 메소드

서브클래스의 오버라이딩을 강제할 목적으로 정의하는 메서드로 외부에서 호출되지 않는다. 
모양은 동일하고 수행할 코드가 다른 메서드를 서브클래스에서 상속받아 오버라이딩하도록 강제성을 부여한다.

이전에 다형성에서 살펴봤지만 상속관계에서 오버라이딩이 기본적으로 강제되지는 못한다. 하지만 추상을 이용하면 이를 강제할 수 있는 것이다.

rutel.tistory.com/343

 

[JAVA] 다형성 / 다이나믹 바인딩

 [ 클래스의 관계 ]  1. Has-A 관계(포함 관계)  => A has a B = A 가 B 를 가지고 있다 = B가 A에 포함되어 있다.  => 일반적인 클래스의 관계이며, 특정 클래스 내에 다른 클래스를 포함시켜 사용하는 관

rutel.tistory.com

 

추상메소드는 아래와 같이 abstract 키워드를 사용하며 body (중괄호) 가 없이 세미콜론으로 선언한다.

[접근제한자] abstract 리턴타입 메서드명 ( [파라미터...] );

추상메소드는 반드시 추상 클래스 내에서만 정의 가능하다. 단, 모든 추상클래스가 추상메서드를 포함하는 것은 아니다

abstract class AbstractClass {
	public abstract void abstractMethod();
}

 

추상 클래스를 상속하는 클래스

추상클래스를 상속하는 클래스는 반드시 추상메소드를 재정의(override) 해 구현(implements)하거나

// The type SubClass must implement the inherited abstract method 
// AbstractClass.abstractMethod()
class SubClass extends AbstractClass { }	// error!

메소드 재정의(method override)하지 않을 경우 추상클래스로 선언해야 한다.

abstract class SubClass extends AbstractClass { }
728x90

final variable

 

값을 변경할 수 없으며 멤버변수에 초기화 값이 없을 시 (blank final), 생성자를 통해 초기화해야한다.

final 변수 이름은 모두 대문자를 쓰는 것이 기본 코딩스타일이다. (공백이나 단어구분시 언더스코어 _ 사용)

public class Ex {

	public static void main(String[] args) {
		FinalVariable f = new FinalVariable();
//		f.NUM1 = 10;
		f.num2 = 20;
		
		FinalVariable2 f2 = new FinalVariable2(100);
		FinalVariable2 f3 = new FinalVariable2(9098);
		
		System.out.println(f2.NUM1 + ", " + f2.NUM2);
		System.out.println(f3.NUM1 + ", " + f3.NUM2);
	}

}

class FinalVariable {
	final int NUM1 = 10;
	int num2 = 20;
	
	public void setNum() {
//		NUM1 = 99;
		num2 = 99;
	}
}

class FinalVariable2 {
	final int NUM1 = 30;
	final int NUM2;
	
	public FinalVariable2(int nUM2) {		
		NUM2 = nUM2;
	}
}

Output :

30, 100
30, 9098

 

 

final method

: 상속받은 메소드를 그대로 사용해야하며 오버라이딩이 금지된다

class FinalMethod {
	public void normalMethod() {
		
	}
	
	public final void finalMethod() {
		System.out.println("super class method");
	}
}

class SubFinalMethod extends FinalMethod {

	@Override
	public void normalMethod() { }	
	// Cannot override the final method from FinalMethod
//	public final void finalMethod() { }
}

 

final 클래스

: 클래스의 상속(is-a 관계)이 불가능하다.

final class FinalClass {

}

// The type subfinal cannot subclass the final class FinalClass
//class subfinal extends FinalClass {
//	
//}

: 대신 포함관계 (has-a)는 가능

final class FinalClass {
	public void method() {

	}
}

class SubFinalClass {
	FinalClass finalClass = new FinalClass();

	public void method() {
		finalClass.method();
	}
}

 

 

상수(Constant)

불변의 값. static final 키워드를 붙여서 표현
static 키워드에 의해 클래스명만으로 접근이 가능하며 모든 인스턴스가 하나의 값을 공유

class Car {
	private String company;    
	public static final String COMPANY_HYUNDAI = "HYUNDAI";
    
    public String getCompany() {
		return company;
	}
	public void setCompany(String company) {
		this.company = company;
	}
}

잘못된 값 입력확률을 줄이고 미리 정의된 값을 쉽게 가져다 쓸 수 있다.

public class Ex2 {
	public static void main(String[] args) {		
		Car car = new Car();		
		car.setCompany(Car.COMPANY_HYUNDAI);
		
		if(car.getCompany().equals(Car.COMPANY_HYUNDAI)) {
			System.out.println("현대자동차");
		} 
	}
}

상수는 생성자에서 초기화 될 수 없다. static은 인스턴스 생성전에 초기화되기 때문

728x90

 [ 클래스의 관계 ]

 1. Has-A 관계(포함 관계)
   => A has a B = A 가 B 를 가지고 있다 = B가 A에 포함되어 있다.
   => 일반적인 클래스의 관계이며, 특정 클래스 내에
        다른 클래스를 포함시켜 사용하는 관계
    ex) class A {
     B b = new B();
    }
2. Is-A 관계(상속 관계)
    => A is a B = A 는 B 이다 = A 는 B 를 상속받은 관계이다. (자신 포함)
    => 초등학생은 학생이다 = 초등학생 is a 학생(O)
       컴퓨터는 기계장치이다 = 컴퓨터 is a 머신(O)
       학생은 학생이다 = 학생 is a 학생(O)
    => 스파이더맨은 사람이다(O)
       사람은 스파이더맨이다(X)
    ex) class A extends B {}
  

 [ instanceof 연산자 ]

 - 좌변의 객체(참조변수)가 우변의 클래스 타입(상속관계)인지 판별하는 연산자
 - 주로 if문에 결합하여 판별하는데 사용되며
  판별 결과가 true 이면 형변환이 가능한 관계(업캐스팅 또는 다운캐스팅)
판별 결과가   false 이면 절대로 형변환 불가능
  
 < 기본 문법 >
 if(A instanceof B) {}
 => A는 참조변수(인스턴스), B는 클래스명

 

public class Ex {

	public static void main(String[] args) {		
		SmartPhone sp = new SmartPhone();
		// 참조변수 sp 로 접근 가능한 SmartPhone 객체의 메서드 : 3개
		sp.call();
		sp.sms();
		sp.kakaoTalk();
		
		if (sp instanceof SmartPhone) {
			System.out.println("sp is a smartphone");
		}
		
		System.out.println("=========================");
		
		if (sp instanceof HandPhone) {
			System.out.println("sp is a HandPhone");
			HandPhone hp = sp;
			hp.call();
			hp.sms();			
		}
		else {
			System.out.println("sp is not a HandPhone");
		}
		
		System.out.println("=========================");
		
		HandPhone hp = new HandPhone();
		hp.call();
		hp.sms();
		
		if (hp instanceof HandPhone) {
			System.out.println("hp is a HandPhone");			
			HandPhone handPhone = hp;
		}
		
		System.out.println("=========================");
		
		if (hp instanceof SmartPhone) {
			System.out.println("hp is a SmartPhone");
		}
		else {
			System.out.println("hp is not a SmartPhone");
//			SmartPhone sp2 = (SmartPhone)hp;
		}
		
		HandPhone hp2 = new SmartPhone();
		hp2.call();
		hp2.sms();
		
		if (hp2 instanceof HandPhone) {
			System.out.println("hp2 is HandPhone");			
		}
		if (hp2 instanceof SmartPhone) {
			System.out.println("hp2 is SmartPhone");
			
		    SmartPhone sp2 = (SmartPhone) hp2;
		    sp2.sms();
		    sp2.kakaoTalk();
		}
		else {
			System.out.println("hp2 is not a SmartPhone");
		}
		
		System.out.println("==========================");
		Child c = new Child();
		
//		Parent p = c;
//		p.parentPrn();
		
		if (c instanceof Parent) {
			System.out.println("c is a Parent");
			Parent p = c;
			p.parentPrn();
		}
		
		Parent p2 = new Parent();
		
		if (p2 instanceof Child) {
			System.out.println("p2 is a Child");
		} else {
			System.out.println("p2 is not a Child");
		}
	}

}

// HandPhone 과 Battery 의 관계는 has-a 관계이다.
class Battery {}

class HandPhone {
	Battery better = new Battery();
	
	public void call() {
		System.out.println("전화!");
	}
	
	public void sms() {
		System.out.println("문자!");
	}
}

// HandPhone 과 SmartPhone 의 관계는 상속관계이다.
class SmartPhone extends HandPhone {
	public void kakaoTalk() {
		System.out.println("카톡!");
	}
}

class Parent {
	public void parentPrn() {
		System.out.println("parentPrn");
	}
}

class Child extends Parent {
	public void childPrn() {
		System.out.println("childPrn");		
	}
}

 

 

상속관계의 오버라이딩

 - 슈퍼클래스의 메서드를 서브클래스에서 오버라이딩 하는 경우
   슈퍼클래스의 메서드는 은닉됨  
 

동적 바인딩 (Dynamic Binding)

 - 상속 관계에서 업캐스팅 후 상속된 메서드를 호출하여 실행할 때
   컴파일(번역) 시점에서의 실행 대상과 실제 실행 단계에서의 실행 대상이 달라지는 것(동적으로 변하는 것)
- 참조 변수의 데이터타입과 무관하게 실제 인스턴스에 따라 실행되는 메서드가 달라짐

public class Ex2 {

	public static void main(String[] args) {
		
		Parent2 p = new Parent2();
		p.parentPrn();
		
		p = new Child2(); // 업캐스팅
		// 참조변수 p 는 Parent2 클래스 타입의 변수이지만
		// 저장된 인스턴스 주소는 Child2 클래스 타입의 인스턴스이다.
		// 따라서, 참조변수 p 를 통해 접근하는 실제 인스턴스는 Child2 이므로
		// p.parentPrn() 메서드를 호출하면 실행되는 메서드도 Child2 의 메서드이다!
		p.parentPrn();
	}

}

class Parent2 {
	public void parentPrn() {
		System.out.println("슈퍼클래스의 parentPrn()");
	}
}

class Child2 extends Parent2 {	
	public void childPrn() {
		System.out.println("서브클래스의 childPrn()");
	}

	@Override
	public void parentPrn() {
		System.out.println("서브클래스에서 오버라이딩 된 parentPrn()");
	}	
}

 

다형성(Polymorphism)

- 하나의 참조변수로 여러 인스턴스를 참조하는 것
= 인스턴스를 다양한 형태로 변환하는 것
= 인스턴스를 업캐스팅하여 슈퍼클래스 타입으로 서브클래스의 멤버 접근

 

public class Ex3 {

	public static void main(String[] args) {
		Circle c = new Circle();
		c.circleDraw();
		
		Rectangle r = new Rectangle();
		r.paint();
		
		Triangle t = new Triangle();
		t.design();
		
		System.out.println("===================");
		c.draw();
		r.draw();
		t.draw();
		System.out.println("===================");
		
		Shape s;		
		s = c;
		s.draw();
		
		s = r;
		s.draw();
		
		s = t;
		s.draw();
	}

}

class Shape { // 도형 클래스
	// 공통적으로 도형을 그릴 수 있는 draw() 메서드 정의
	public void draw() {
		System.out.println("도형 그리기!");
	}
}

class Circle extends Shape {
	public void circleDraw() {
		System.out.println("원 그리기!");
	}

	@Override
	public void draw() {
		System.out.println("원 그리기!");
	}
	
}

class Rectangle extends Shape {
	public void paint() {
		System.out.println("사각형 그리기!");
	}
	
	@Override
	public void draw() {
		System.out.println("사각형 그리기!");
	}
}

class Triangle extends Shape {
	public void design() {
		System.out.println("삼각형 그리기!");
	}
	
	@Override
	public void draw() {
		System.out.println("삼각형 그리기!");
		
	}
}

Output : 

원 그리기!
사각형 그리기!
삼각형 그리기!
===================
원 그리기!
사각형 그리기!
삼각형 그리기!
===================
원 그리기!
사각형 그리기!
삼각형 그리기!

 

 

ex) 다형성은 아래와 같이 메소드의 파라미터를 통해서도 활용할 수 있다.

: 파라미터로 Circle, Rectangle, Triangle 인스턴스 전달 -> Shape 타입으로 업캐스팅됨

public class Ex3 {
	public static void main(String[] args) {		
		drawShape(new Circle());
//		drawShape(new Rectangle());  
		polymorphismDrawShape(new Circle());
		polymorphismDrawShape(new Rectangle());
		polymorphismDrawShape(new Triangle());
	}
	
	public static void drawShape(Circle c) {
		c.draw();
	}
	
	public static void polymorphismDrawShape(Shape s) {
		s.draw();
	}
}

class Shape { // 도형 클래스
	// 공통적으로 도형을 그릴 수 있는 draw() 메서드 정의
	public void draw() {
		System.out.println("도형 그리기!");
	}
}

class Circle extends Shape {
	@Override
	public void draw() {
		System.out.println("원 그리기!");
	}
	
}
(...)

ex) 다형성을 배열에 활용하는 경우 (업캐스팅)

	Circle[] cArr = new Circle[3];
		cArr[0] = new Circle();
//		cArr[1] = new Rectangle();
		
		Shape[] sArr = new Shape[3];
		sArr[0] = new Circle();
		sArr[1] = new Rectangle();
		sArr[2] = new Triangle();
		
		for (Shape shape : sArr) {
			shape.draw();
		}

'Study > Java' 카테고리의 다른 글

[JAVA] 추상(abstract)  (0) 2021.03.09
[JAVA] final 키워드 / 상수(constant)  (0) 2021.03.09
JAVA - getter, setter  (0) 2021.02.09
JAVA - 파일 내 특정 문자열이 포함된 행을 제거  (0) 2021.02.04
JAVA에서의 데이터 타입  (0) 2021.01.11
728x90

레퍼런스 (오라클 12.2) :

docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/Functions.html#GUID-D079EFD3-C683-441F-977E-2C9503089982

 

SQL Language Reference

 

docs.oracle.com

 

concat (문자열 결합)

SQL> select concat('Hello', 'World')
  2  from dual;

CONCAT('HE
----------
HelloWorld

 

substr (문자열 자르기)

SQL> select substr('HelloWorld', 1, 5)
  2  from dual;

SUBST
-----
Hello

substr ('자를문자열', 시작인덱스(1부터시작), 자를 문자열 수)

 

시작인덱스는 문자열 끝부터 역순세기도 지원한다. (끝자리가 -1)

SQL> select substr('HelloWorld', -3, 3)
  2  from dual;

SUB
---
rld

자를 문자열 수는 왼쪽에서 오른쪽 방향으로만 지원한다. 따라서 아래와 같은 방법으론 원하는 결과(rld출력)가 나오지 않는다.

SQL> select substr('HelloWorld', -1, 3)
  2  from dual;

S
-
d
SQL> select substr('HelloWorld', -1, -3)
  2  from dual;

S
-

substr함수를 where절에 응용

SQL> select last_name, hire_date
  2  from employees
  3  where substr(hire_date, -2, 2) = '04';

LAST_NAME		  HIRE_DATE
------------------------- ---------
Weiss			  18-JUL-04
Mallin			  14-JUN-04
Russell 		  01-OCT-04
(...)

 

length (문자열 길이 구하기)

SQL> select length('helloworld') * 7 + 2
  2  from dual;

LENGTH('HELLOWORLD')*7+2
------------------------
		      72

helloworld의 길이는 10이므로 10 x 7 + 2의 연산이 이루어져 72가 출력된다.

 

instr (문자열 인덱스 찾기)

레퍼런스 : docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/INSTR.html#GUID-47E3A7C4-ED72-458D-A1FA-25A9AD3BE113

 

SQL Language Reference

 

docs.oracle.com

문법

{ INSTR
| INSTRB
| INSTRC
| INSTR2
| INSTR4
}
(string , substring [, position [, occurrence ] ])

|   = or
[   = option
(전체문자열, 찾고싶은 문자열 [, 해당인덱스부터 검색 [, 찾은 문자열 여러개면 n번째 나타나는 문자열인지 지정 ] ])

 

반환값은 찾은 인덱스 (정수)

 

예)

SQL> select instr('hello', 'l')
  2  from dual;

INSTR('HELLO','L')
------------------
		 3

예) substr과 결합해 응용

SQL> select substr('helloworld', instr('helloworld', 'h'), 4)
  2  from dual;

SUBS
----
hell

예)

SELECT INSTR('CORPORATE FLOOR','OR', 3, 2) "Instring"
  2    FROM DUAL;

  Instring
----------
	14

위의 INSTR 함수의 3번째 인자는 "찾기 시작할 인덱스", 4번째 인자는 "두번째로 찾은 문자열"

 

max (최대 길이 구하기)

예) last_name컬럼 데이터의 최대길이 구하기

SQL> select max(length(last_name))
  2  from employees;

MAX(LENGTH(LAST_NAME))
----------------------
		    11

 

lpad, rpad

(길이가 n이 되도록 문자식으로 채운 표현식 반환.

lpad는 왼쪽부터, rpad는 오른쪽부터 채움)

예)

SQL> select lpad(salary, 10, '*') as lpad, rpad(salary, 10, '*') as rpad
  2  from employees;

LPAD		     RPAD
-------------------- --------------------
*****24000	     24000*****
*****17000	     17000*****
*****17000	     17000*****
(...)

암시적 형변환하여 숫자값을 문자값으로 변환하여 결과 출력

 

예) 왼쪽에 공백을 넣어 정렬 맞추기

SQL> select lpad(last_name, 11, ' ') || ' is babo. '
  2  from employees;

LPAD(LAST_NAME,11,'')||'ISBABO.'
------------------------------------------------------
       Abel is babo.
       Ande is babo.
   Atkinson is babo.
     Austin is babo.

 

replace (문자열 치환)

SQL> select replace('jack and jue', 'j', 'bl')
  2  from dual;

REPLACE('JACKA
--------------
black and blue

TRIM

  • 입력받은 문자열 양쪽 끝의 지정 문자 제거

SQL> SELECT TRIM(' ' FROM '     HelloWorld    ')
  2  FROM dual;
  
TRIM(''FRO
----------
HelloWorld

'     HelloWorld    '의 양끝에서 ' ' 가 제거된 모습

 

 

'DB' 카테고리의 다른 글

[오라클 DB] 일반 함수/그룹함수  (0) 2021.03.10
[오라클 DB] 함수-숫자  (0) 2021.03.10
[오라클 DB] DQL 심화학습  (0) 2021.02.19
[오라클 DB] 온라인에서 Oracle SQL 테스트하기  (0) 2021.02.19
[오라클 DB] DQL  (0) 2021.02.03
728x90

0. 유저생성 및 테이블 정의

0-1. root가 아닌 개별 유저 생성

mysql> grant select,insert,update,delete,create,alter,drop
    -> on jspdb7.* to 'jspid'@'localhost'
    -> identified by 'jsppass';
Query OK, 0 rows affected, 1 warning (0.19 sec)

유저가 없으면 경고가 뜨지만 자동생성되니 무시하고 진행

 

0-2. 테이블 생성

mysql> create table member(
    -> id varchar(20) primary key,
    -> pass varchar(20),
    -> name varchar(20),
    -> date datetime
    -> );

 

1. 테이블 데이터를 가져오는 jsp소스

<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>jsp4/list.jsp</h1>
	<%
	Class.forName("com.mysql.jdbc.Driver");
	String dbUrl = "jdbc:mysql://localhost:3306/jspdb7";
	String dbUser = "jspid";
	String dbPass = "jsppass";
	Connection con = DriverManager.getConnection
			(dbUrl, dbUser, dbPass);
	String sql = "select * from member;";
	PreparedStatement pstmt = con.prepareStatement(sql);
	ResultSet rs = pstmt.executeQuery(sql);
	SimpleDateFormat sdf=new SimpleDateFormat
			("yyyy-MM-dd HH:mm:ss");
	%>
	<table border="1">
		<tr>
			<th>아이디</th>
			<th>비밀번호</th>
			<th>이름</th>
			<th>가입날짜</th>
		</tr>
		<%
		while (rs.next()) {
		%>
		<tr>
			<td><%=rs.getString("id")%></td>
			<td><%=rs.getString("pass")%></td>
			<td><%=rs.getString("name")%></td>
			<td><%=sdf.format(rs.getTimestamp("date"))%></td>
		</tr>
		<%
		}
		%>
	</table>
</body>
</html>

ResultSet은 next메소드를 통해 다음 레코드 값을 가져올 수 있으며 레코드가 있을 시 1을 반환한다.

실행해보면 가입날짜 끝에 .0 이 붙어 나오는데 26라인의 SimpleDateFormat 내장객체를 이용해 43라인에서 포맷을 변환해줘야한다.

+ Recent posts