반응형
SQL 자주 발생하는 오류 총정리

💥 SQL에서 자주 나타나는 오류 총정리! (실무 & 시험 대비)

SQL 초보부터 중급자까지 꼭 알아야 할 SQL 오류 케이스 TOP 8을 실전 예제와 함께 정리했습니다!

ORA-00904: invalid identifier

원인: 존재하지 않는 컬럼명을 조회하려 할 때

SELECT empnmae FROM employees;

해결: 컬럼명 오타 확인 (예: empname)

ORA-00936: missing expression

원인: SELECT, WHERE 등에서 표현식이 빠짐

SELECT FROM employees;

해결: SELECT 다음에는 반드시 컬럼명이 와야 함

ORA-00933: SQL command not properly ended

원인: SQL 문이 올바르게 끝나지 않음

UPDATE employees SET salary = 5000
WHERE employee_id = 100
-- 세미콜론 빠짐
    

해결: SQL 문 끝에 ; 확인!

ORA-00911: invalid character

원인: 허용되지 않는 문자 포함

SELECT * FROM employees WHERE last_name = 'O'Brien';

해결: 작은따옴표는 두 번 사용 'O''Brien'

ORA-01722: invalid number

원인: 숫자로 변환 불가능한 값을 숫자형 컬럼에 비교

SELECT * FROM employees WHERE salary = 'abc';

해결: 숫자형 컬럼에는 숫자만, 문자열은 CAST 사용

ORA-00937: not a single-group group function

원인: GROUP BY 없이 집계함수와 일반 컬럼을 같이 사용

SELECT department_id, AVG(salary)
FROM employees;
    

해결:

SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id;
    

ORA-00001: unique constraint violated

원인: PK 또는 UNIQUE 컬럼에 중복 값 입력

INSERT INTO departments (department_id, department_name)
VALUES (10, 'Sales'); -- 이미 존재하는 ID
    

해결: 중복되지 않는 값 입력

ORA-02291: integrity constraint violated - parent key not found

원인: 자식 테이블에서 참조하는 부모 키가 없음

INSERT INTO employees (employee_id, manager_id)
VALUES (300, 9999); -- manager_id 9999가 없음
    

해결: 부모 테이블에 해당 키가 있는지 먼저 확인

🧠 시험 꿀팁 요약 테이블

오류 코드 기억 포인트
ORA-00904오타? 컬럼명 확인
ORA-00936SELECT 절 점검
ORA-00933세미콜론 확인
ORA-00911문자열 escape
ORA-01722숫자형 확인
ORA-00937GROUP BY 추가
ORA-00001중복 입력 방지
ORA-02291FK 참조 키 확인

✨ 마무리

SQL은 작은 오타 하나로도 오류가 날 수 있어요. 에러 메시지를 잘 읽고 원인을 유추하는 연습이 중요합니다! 😊

반응형

'SQL > SQL_이론' 카테고리의 다른 글

SQL문의 실행순서  (0) 2024.09.19
트랜잭션(Transaction)  (0) 2024.09.19
SQL의 종류  (1) 2024.09.19
관계형 데이터베이스와 테이블  (0) 2024.09.19
SELECT 문  (0) 2024.06.25
반응형

SQL문의 실행순서를 요약하면 아래와 같습니다.

  • 개발자가 작성한 SQL문(DDL, DML, DCL 등)은 3단계를 걸쳐서 실행된다. SQL문의 문법을 검사하고 구문 분석을 한다.
  • 구문 분석 이후에 SQL을 실행한다. SQL이 실행되면 데이터를 인출하게 된다.

▶ SQL 실행 순서

SQL 실행 순서 설명
파싱(Parsing) - SQL 문의 문법을 확인하고 구문 분석한다.
- 구문 분석한 SQL문은 Library Cache에 저장된다.
실행(Execution) 옵티마이저(Optimizer)가 수립한 실행 계획에 따라 SQL을 실행한다.
인출(Fetch) 데이터를 읽어서 전송한다.

 

  1. 파싱(Parsing)
    • SQL 문이 데이터베이스로 들어오면, 파싱 단계에서 문법이 올바른지 먼저 확인합니다. 이 과정에서 데이터베이스는 SQL 문을 구문 분석(파싱)해서 명령어가 무엇을 의미하는지 이해하고, 최종적으로 문법 오류가 있는지 체크합니다. 만약 문법적으로 문제가 없다면, 그 SQL 문을 Library Cache라는 메모리 공간에 저장해두죠. 이 작업은 이후 동일한 SQL 문이 또 실행될 때, 이미 분석된 SQL 문을 재사용해서 속도를 빠르게 하기 위해서예요.
  2. 실행(Execution)
    • 파싱이 끝나고 나면, 실행 단계로 넘어가요. 이 단계에서 데이터베이스는 **옵티마이저(Optimizer)**라는 내부 알고리즘을 사용해, SQL을 어떻게 효율적으로 실행할지 '실행 계획'을 세워요. 옵티마이저는 여러 가지 방법 중에서 가장 빠르고 적합한 방법을 선택해 실행하게 돼요. 예를 들어, 특정 테이블에서 데이터를 조회할 때, 인덱스를 사용할지, 전체 테이블을 스캔할지를 결정하는 게 바로 이 과정이에요.
  3. 인출(Fetch)
    • SQL 문이 실행되면, 그 결과를 가져오는 인출 단계가 진행돼요. 데이터를 데이터베이스에서 읽어온 후, 요청한 사용자에게 전송해주는 단계예요. 예를 들어, "나이가 18세 이상인 사람들의 이름을 조회"하라는 명령어를 실행했다면, 그 결과를 가져와서 화면에 보여주는 게 이 단계죠.

요약하자면, 파싱은 SQL 문을 분석하고 준비하는 단계, 실행은 실제로 SQL을 처리하는 단계, 인출은 실행 결과를 가져오는 단계예요. 이 세 단계를 통해 데이터베이스가 우리가 요청한 데이터를 안전하고 빠르게 처리해주는 것입니다.

반응형

'SQL > SQL_이론' 카테고리의 다른 글

SQL에서 자주보이는 오류들  (1) 2025.05.25
트랜잭션(Transaction)  (0) 2024.09.19
SQL의 종류  (1) 2024.09.19
관계형 데이터베이스와 테이블  (0) 2024.09.19
SELECT 문  (0) 2024.06.25
반응형

 

트랜잭션은 데이터베이스의 작업을 처리하는 단위이다.

▶ 트랜잭션의 특성

트랜잭션 특성 설명
원자성(Atomicity) - 트랜잭션은 데이터베이스 연산의 전부가 실행되거나 전혀 실행되지 않아야 한다 (ALL OR NOTHING)
- 즉, 트랜잭션의 처리가 완전히 끝나지 않았을 경우는 실행되지 않은 상태와 같아야 한다.
일관성(Consistency) - 트랜잭션 실행결과로 데이터베이스의 상태가 모순되지 않아야 한다.
- 트랜잭션 실행 후에도 일관성이 유지되어야 한다.
고립성(Isolation) - 트랜잭션 실행 중에 생성하는 연산의 중간결과는 다른 트랜잭션이 접근할 수 없다.
- 즉, 부분적인 실행 결과를 다른 트랜잭션이 볼 수 없다.
영속성(Durability) 트랜잭션이 그 실행을 성공적으로 완료하면 그 결관느 영구적 보장이 되어야 한다.

 

좀 더 쉽게 설명하면 다음과 같다.

 

  1. 원자성(Atomicity)
    • 내가 책을 한 권 샀다고 상상해보자. 책을 사는 과정에는 "돈을 내기"와 "책을 받기"라는 두 가지 행동이 있다. 이 두 가지는 한꺼번에 이루어져야 한다. 만약 책을 샀는데 돈만 내고 책을 못 받으면 안 될 것이다. 반대로 책만 받고 돈을 안 냈다면 그것도 문제가 된다. 그래서 원자성이란, 둘 다 동시에 성공해야 하고, 하나라도 실패하면 둘 다 취소돼서 처음 상태로 돌아가야 한다는 것이다.
  2. 일관성(Consistency)
    • 엄마가 장난감 가게에서 장난감을 사려고 할 때, 엄마는 돈을 줄 테니까 장난감 가게는 장난감을 준다. 그런데 만약 가게에서 장난감이 없으면 엄마가 돈을 줘도 장난감을 못 받게된다. 일관성은 이런 상황을 막는 것이다. 돈을 줬으면 반드시 장난감을 받아야 하고, 반대로 장난감이 없으면 돈을 내는 일이 생기지 않도록 해야 한다.
  3. 고립성(Isolation)
    • 친구가 나에게 초콜릿을 하나 주는 중이라고 상상해보자. 그 순간에 다른 친구가 와서 "초콜릿 너 다 먹었어?"라고 물으면, 너는 아직 초콜릿을 받고 있는 중이라 뭐라고 대답해야 할지 헷갈릴 것이다. 고립성이란, 너가 초콜릿을 다 받을 때까지 다른 친구가 그 일에 끼어들지 못하게 막는 것이다. 너가 초콜릿을 다 받으면 그제야 "응, 다 먹었어!"라고 말할 수 있는 것이다.
  4. 영속성(Durability)
    • 내가 그림을 그렸을 때, 그 그림이 물에 젖어서 없어지면 속상할 것이다. 영속성은 한 번 성공적으로 그린 그림이 절대로 없어지지 않도록 보관해주는 것이다. 데이터베이스도 마찬가지로, 트랜잭션이 성공적으로 끝나면 그 결과가 절대로 사라지지 않도록 안전하게 보관하는 것이다.

이렇게 트랜잭션은 중요한 일을 할 때, 확실하게 처리하고 중간에 문제가 생기지 않도록 여러 규칙들을 지키는 것이다.

반응형

'SQL > SQL_이론' 카테고리의 다른 글

SQL에서 자주보이는 오류들  (1) 2025.05.25
SQL문의 실행순서  (0) 2024.09.19
SQL의 종류  (1) 2024.09.19
관계형 데이터베이스와 테이블  (0) 2024.09.19
SELECT 문  (0) 2024.06.25
반응형
SQL은 컴퓨터에서 데이터를 다루는 특별한 언어입니다. 마치 우리가 국어나 영어를 사용해 이야기를 나누는 것처럼, SQL은 컴퓨터와 데이터를 주고받는 방법입니다. 데이터를 쉽게 정리하고, 저장하고, 바꾸는 일을 할 수 있도록 도와주는 중요한 도구라고 할 수 있습니다.

 

SQL이 하는 일

SQL은 데이터베이스라는 곳에서 일을 합니다. 데이터베이스는 정보를 모아둔 큰 상자 같은 곳이라고 생각하면 됩니다. 예를 들어, 학교에서 학생들의 이름, 나이, 성적을 기록해두는 곳이 데이터베이스 입니다. SQL을 사용하면 이 상자 속에서 정보를 쉽게 찾고, 더하고, 바꾸고, 없앨 수 있습니다.

 

SQL의 종류

SQL에는 크게 네 가지 종류가 있습니다. 각 종류마다 하는 일이 조금씩 다릅니다.

  1. DDL (데이터 정의 언어)
    이건 데이터를 넣을 그릇, 즉 테이블을 만드는 일을 합니다.
    예를 들어, 학교에서 학생 정보를 저장할 테이블을 만들려면, DDL을 사용합니다.
    • CREATE: 테이블을 새로 만듭니다.
    • ALTER: 테이블에 더 넣을 공간이 필요하면 수정합니다.
    • DROP: 더 이상 필요 없는 테이블을 삭제합니다.
    예시:이 코드는 "학생"이라는 테이블을 만들고, 그 테이블에 이름, 나이, 성적을 기록할 수 있도록 해줍니다.
CREATE TABLE 학생 (이름 VARCHAR(20), 나이 INT, 성적 INT);
  1. DML (데이터 조작 언어)
    이건 테이블 안의 데이터를 직접 다루는 언어입니다.
    • INSERT: 새 데이터를 테이블에 넣습니다.
    • UPDATE: 이미 있는 데이터를 수정합니다.
    • DELETE: 데이터를 삭제합니다.
    • SELECT: 테이블에서 데이터를 찾아서 보여줍니다.
    예시:이 코드는 "홍길동"이라는 학생 정보를 테이블에 넣습니다.
INSERT INTO 학생 (이름, 나이, 성적) VALUES ('홍길동', 12, 90);
  1. DCL (데이터 제어 언어)
    이건 데이터를 누가 사용할 수 있는지 권한을 주는 역할을 합니다.
    • GRANT: 다른 사람이 데이터를 사용할 수 있도록 허락합니다.
    • REVOKE: 데이터를 사용할 수 없도록 권한을 회수합니다.
  2. TCL (트랜잭션 제어 언어)
    여러 개의 일을 한 번에 묶어서 실행하고, 실수했을 때 다시 원래 상태로 되돌리는 것을 도와줍니다.
    • COMMIT: 여러 작업을 다 끝내고 저장합니다.
    • ROLLBACK: 실수하면 다시 이전 상태로 복원합니다.
    예시:이 코드를 사용하면 실수한 일을 모두 취소하고 처음 상태로 되돌려줍니다.
ROLLBACK;

 

이렇게 SQL은 데이터를 다루는 여러 가지 방법을 제공해서, 마치 우리가 장난감을 정리하듯이 데이터를 정리하고 다룰 수 있습니다.

반응형

'SQL > SQL_이론' 카테고리의 다른 글

SQL문의 실행순서  (0) 2024.09.19
트랜잭션(Transaction)  (0) 2024.09.19
관계형 데이터베이스와 테이블  (0) 2024.09.19
SELECT 문  (0) 2024.06.25
WHERE 절  (0) 2024.06.25
반응형

1. 관계형 데이터베이스

(1) 데이터베이스와 데이터베이스 관리 시스템의 차이점

  • 데이터베이스는 데이터를 어떠한 형태의 자료구조로 사용하느냐에 따라서 나누어진다.
  • 데이터베이스의 종류는 계층형, 네트워크형 데이터베이스, 관계형 데이터베이스 등이 있다.
  • 계층형 데이터베이스는 트리 형태의 자료구조에 데이터를 저장하고 관리하며, 네트워크는 오너와 멤버 형태로 데이터를 저장한다.
  • 계층형 데이터베이스는 1대 N 관계를 표현한다.
  • 네트워크 데이터베이스는 1대N과 함께 M대 N 표현도 가능하다.
  • 관계형 데이터베이스는 릴레이션에 데이터를 저장하고 관리한다.
  • 관계형 데이터베이스는 릴레이션을 사용해서 집합 연산과 관계 연산을 할 수 있다.
  • 데이터베이스 관리 시스템은 계층형 데이터베이스, 네트워크 데이터베이스, 관계형 데이터베이스 등을 관리하기 위한 소프트웨어를 의미하며, 일명 DBMS라고 한다.
  • DBMS의 종류에는 Oracle, MS-SQL, MySQL, Sybase 등이 있으며 모두 관계형 데이터베이스를 지원한다.

(2) 관계형 데이터베이스 집합 연산과 관계 연산

  • 관계형 데이터베이스의 특징은 릴레이션을 사용해서 집합 연산과 관계 연산을 할 수 있다.

▶ 집합 연산

집합 연산 설명
합집합(Union) - 두 개의 릴레이션을 하나로 합하는 것이다.
- 중복된 행(튜플)은 한 번만 조회된다.
차집합(Difference) 본래 릴레이션에는 존재하고 다른 릴레이션에는 존재하지 않는 것을 조회한다.
교집합(Intersection) 두 개의 릴레이션 간에 공통된 것을 조회한다.
곱집합(Cartesian product) 각 릴레이션에 존재하는 모든 데이터를 조합하여 연산한다.

 

▶ 관계 연산

관계 연산 설명
선택 연산(Selection) 릴레이션에서 조건에 맞는 행(튜플)만을 조회한다.
투영 연산(Projection) 릴레이션에서 조건에 맞는 속성만을 조회한다.
결합 연산(Join) 여러 릴레이션의 공통된 속성을 사용해서 새로운 릴레이션을 만들어 낸다.
나누기 연산(Division) 기준 릴레이션에서 나누는 릴레이션이 가지고 있는 속성과 동일한 값을 가지는 행(튜플)을 추출하고 나누는 릴레이션의 속성을 삭제한 후 중복된 행을 제거하는 연산이다.

 

2. 테이블의 구조

  • 관계형 데이터베이스는 릴레이션에 데이터를 저장하고 릴레이션을 사용해서 집합 연산 및 관계 연산을 지원하여 다양한 형태로 데이터를 조회할 수 있다.
  • 릴레이션은 최종적으로 데이터베이스 관리 시스템에서 테이블로 만들어진다.
  • 기본키(Primary Key)는 하나의 테이블에서 유일성(Unique)과 최소성, Not Null을 만족하면서 해당 테이블을 대표하는 것이다. EMP 테이블에서는 사원번호가 기본키가 된다.
  • 테이블은 행과 칼럼으로 구성된다. 그중에서 행(ROW)은 하나의 테이블에 저장되는 값으로 튜플(Tuple)이라고도 한다.
  • 칼럼(Column)은 어떤 데이터를 저장하기 위한 필드(Field)로 속성(Attribute)이라고도 한다.
  • 외래키(Foreign Key)는 다른 테이블의 기본키를 참조(조인)하는 칼럼이다. 예를 들어 EMP 테이블의 부서코드는 DEPT 테이블의 기본키인 부서코드를 참조한다.
  • 외래키는 관계 연산 중에서 결합 연산(Join)을 하기 위해서 사용한다.

 

[정리]

**데이터베이스 개요**

- 데이터베이스는 계층형, 네트워크형, 관계형 등 다양한 종류가 있으며, 각각 다른 자료구조를 사용한다
- 관계형 데이터베이스는 릴레이션을 사용하여 데이터를 저장하고 관리한다
- DBMS(데이터베이스 관리 시스템)는 이러한 데이터베이스를 관리하기 위한 소프트웨어이다

**관계형 데이터베이스 연산**

- 관계형 데이터베이스는 집합 연산(합집합, 차집합, 교집합, 곱집합)과 관계 연산(선택, 투영, 결합, 나누기)을 지원한다
- 이러한 연산들을 통해 다양한 형태로 데이터를 조회할 수 있다

**테이블 구조**

- 테이블은 행(튜플)과 열(속성)로 구성되며, 기본키는 유일성과 최소성, Not Null을 만족하는 대표 속성이다
- 외래키는 다른 테이블의 기본키를 참조하는 칼럼으로, 주로 결합 연산에 사용된다

반응형

'SQL > SQL_이론' 카테고리의 다른 글

트랜잭션(Transaction)  (0) 2024.09.19
SQL의 종류  (1) 2024.09.19
SELECT 문  (0) 2024.06.25
WHERE 절  (0) 2024.06.25
프로시저  (0) 2023.09.15
반응형

SELECT

저장되어 있는 데이터를 조회하고자 할 때 사용하는 명령어

SELECT 컬럼1, 컬럼2, ... FROM 테이블명 WHERE 컬럼1 = '아무개';

컬럼을 따로 명시하지 않고 *(asterisk)를 쓰면 전체 컬럼이 조회되며 조회되는 컬럼의 순서는 테이블의 컬럼 순서와 동일, 별도의 WHERE 절이 없으면 테이블의 전체 Row가 조회됨!

SELECT * FROM 테이블;
  • 테이블이나 컬럼명에 별도의 별칭(Alias)를 붙여줄 수 있음
  • 여러개의 테이블을 조인하거나 서브쿼리가 있을 때 컬럼명 앞에 테이블명을 같이 명시해야 하는 경우

예제

다음 중 문법 에러가 발생하는 SQL은 어느 것일까?

1. select d.dept_no from departments d;
2. select departments.dept_no from departments t where dept_no = 'd009';
3. select departments.dept_no from departments where dept_no = 'd009';
4. select dept_no from departments t where t.dept_no = 'd009';

정답 ) 2

풀이) 테이블 명에 Alias를 설정했을 경우 컬럼명에 테이블 명 대신 Alias를 이용해야 한다.

select t.dept_no from departments t where dept_no = 'd009';

산술연산자

  • 수학에서 사용하는 사칙연산의 기능을 가진 연산자
  • NUMBER DATE 유형의 데이터와 같이 사용할 수 있다.
  • ( ) : 괄호로 우선순위를 조정할 수 있음
    • : 곱하기
    • / : 나누기
    • : 더하기
    • : 빼기
select 10+5, 10-5, 10*5, 10/5 from dual;
select * from sample;
select col1 + col2 AS A,
	     col1 - col2 AS B,
       col1 * col2 AS C,
       col1 / col2 AS D
from sample;
select col1+col2*col1 AS R1,
       (col1+col2)*col1 AS R2
from sample;

예제

다음 SQL의 결과는 무엇인가?

select col1 + col2 AS RESULT from sample2;

[SAMPLE2 테이블]

정답)

해설) 다른 컬럼끼리 연산(가로연산)에서 NULL이 포함되어 있으면 결과값은 Null이 된다.

 

합성 연산자

  • 문자와 문자를 연결할 때 사용하는 연산자
-- Oracle
SELECT 'S'||'Q'||'L'||'개'||'발'||'자' AS SQLD FROM DUAL;
-- MySQL
SELECT CONCAT('S', 'Q', 'L', '개', '발', '자') AS SQLD FROM DUAL;
select * from sample3;
-- Oracle
select col1 || ' ' || 'SQLD' || ' ' || col2 AS RESULT from sample3;

-- MySQL
select concat(col1, ' ', 'SQLD', ' ', col2) AS RESULT from sample3;

 

반응형

'SQL > SQL_이론' 카테고리의 다른 글

SQL의 종류  (1) 2024.09.19
관계형 데이터베이스와 테이블  (0) 2024.09.19
WHERE 절  (0) 2024.06.25
프로시저  (0) 2023.09.15
VIEW  (0) 2023.09.15
반응형

INSERT를 제외한 DML문을 수행할 때 원하는 데이터만 골라 수행할 수 있도록 해주는 구문

SELECT 컬럼명1, 컬럼명2, ... FROM 테이블명 WHERE 조건절;
SELECT * FROM employees
WHERE gender = 'M';
UPDATE 테이블명 SET 컬럼명 = 새로운데이터 WHERE 조건절;

DELETE FROM 테이블명 WHERE 조건절;

(1) 비교 연산자

연산자의미예시

= 같음 WHERE COL = 10
< 작음 WHERE COL < 10
< = 작거나 같음 WHERE COL < = 10
> WHERE COL > 10
> = 크거나 같음 WHERE COL > = 10

다음 쿼리는 first_name이 Georgi인 행을 조회한다.

SELECT first_name, last_name, gender FROM employees
WHERE first_name = 'Georgi';

다음 쿼리는 salary가 60000보다 작은 행을 조회한다.

select emp_no, salary from salaries
where salary < 60000;

다음 쿼리는 first_name과 Georgi의 데이터 타입이 맞지 않아 에러가 발생한다.

SELECT first_name, last_name, gender FROM employees
WHERE first_name = Georgi;
💡 first_name과 같은 문자형 컬럼을 비교 조건으로 사용하려면 우측 상수값을 반드시 인용부호로 감싸주어야 한다.

 

(2) 부정 비교 연산자

연산자의미예시

! = 같지 않음 where col ! = 10
^= 같지 않음 where col ^= 10
<> 같지 않음 where col <> 10
not 컬럼명 = 같지 않음 where not col = 10
not 컬럼명 > 크지 않음 where not col > 10

다음 쿼리는 first_name 이 Georgi 가 아닌 행을 조회한다.

SELECT first_name, last_name, gender FROM employees
WHERE first_name <> 'Georgi';
💡 논리 연산자는 SQL에 명시된 순서와는 관계없이 () → NOT → AND → OR 순으로 처리된다.

 

💡 조건식에서 컬럼명은 일반적으로 좌측에 위치하지만 우측에 위치해도 정상 작동한다.

 

반응형

'SQL > SQL_이론' 카테고리의 다른 글

관계형 데이터베이스와 테이블  (0) 2024.09.19
SELECT 문  (0) 2024.06.25
프로시저  (0) 2023.09.15
VIEW  (0) 2023.09.15
SYSTEM_ROLE  (0) 2023.09.14
반응형

procedure

-- 19_Procedure
-- pl/sql : 프로시저/펑션, DB 프로그래밍 분야(SQL 숙련자들)
-- 난이도가 높음
-- 소스 : Oracle DB에 저장됨
-- 장점 : 1) 성능향상
-- 자바/JS 처럼 코딩하는 것을 말함
-- 코딩 특징 : 1) 제어문 (조건문/반복문), 변수/상수
-- 예제1) 
-- 화면 출력 모드 변경 : ON (출력 켜기)
SET SERVEROUTPUT ON;
-- 입력 : 대화상자 입력값이 변수명에 입력됨
-- 사용법 ) ACCEPT 변수명 prompt '문자열'
-- p_변수명 : 입력용 변수
-- v_변수명 : 단순 변수
ACCEPT p_num1 prompt '첫번째 숫자를 입력하세요'
ACCEPT p_num2 prompt '두번째 숫자를 입력하세요'

-- 1) 선언부 : DECLARE
DECLARE
-- 변수초기화, 변수 정의 : 숫자(NUMBER), 문자(VARCHAR2), 날짜(DATE) [자료형]
    v_sum NUMBER(10);
BEGIN
-- 2) 실행부 : BEGIN
-- 프로시저 코딩 : 업무 코딩(비지니스 로직 코딩 : 실무용어)
-- 사용법) 입력값(p_num) 변수 : &변수명 사용
--        대입연산자 - :=
--        v_sum      : 선언부에서 정의한 변수
    v_sum := &p_num1 + &p_num2; -- 입력값 2개를 더하기
    
-- 문자열 붙이기 : 문자열 || 문자열2 ...
    dbms_output.put_line('총합은 : ' || v_sum); -- 화면에 1줄씩 출력하는 함수
END;
/

결과 =======================
신규:DECLARE
    v_sum NUMBER(10);
BEGIN
    v_sum := 10 + 20;

    dbms_output.put_line('총합은 : ' || v_sum);
END;
총합은 : 30


PL/SQL 프로시저가 성공적으로 완료되었습니다.
=======================


-- 예제 2) 입력받은 사원번호에 해당하는 월급 출력하기 : EMPLOYEE
-- 입력값 : 7788 (SCOTT)
ACCEPT p_empno prompt '사원번호를 입력하세요'

-- 프로시저 코딩
DECLARE
    -- 1) 선언부 : 변수 정의
    v_sal NUMBER(10); -- 10자리 숫자
BEGIN
    -- 2) 실행부
    -- 사용법) SELECT 컬럼명 INTO 변수명 FROM 테이블명 : 컬럼의 값이 변수에 저장됨
    SELECT SALARY INTO v_sal
    FROM EMPLOYEE
    WHERE ENO = &p_empno;
    
    -- 3) 결과 출력 : v_sal
    dbms_output.put_line('해당 사원의 월급은 : ' || v_sal);
END;
/

=== 결과
해당 사원의 월급은 : 3000
===

-- 예제 3) 조건문 : IF/ELSIF/ELSE/END IF
-- 입력값 변수 : p_num
ACCEPT p_num PROMPT '숫자를 입력하세요.'
-- DECLARE(선언부) 생략 : 변수 정의할것이 없으면 생략가능
BEGIN
-- 실행부
-- 사용법) IF 조건식 THEN
--           실행문;
--        ELSE
--           실행문2;
--        END IF
-- MOD(값, 나눌값) : 나머지 연산하는 함수
-- 비교연산자 : =
    IF MOD(&p_num, 2) = 0 THEN
        DBMS_OUTPUT.PUT_LINE('짝수입니다.'); -- 화면출력
    ELSE 
        DBMS_OUTPUT.PUT_LINE('홀수입니다.');
    END IF;
END;
/

-- 예제 4) 조건문 계속 : IF/ELSIF/ELSE/END IF;
--   사원테이블에 사원명을 입력받아 급여가 3000 이상이면 고소득자입니다. 출력
--                                   2000 이상이면 중간 소득자입니다. 출력
--                                   모두 아니면 저소득자입니다. 출력
-- 입력값 변수 : p_ename
ACCEPT p_ename PROMPT '사원 이름를 입력하세요.'
-- 선언부(정의부)
DECLARE
    -- 변수 2개 : 
    -- 대문자 변환 함수 : UPPER(문자열)
    -- 대상 테이블의 컬럼의 자료형을 참조해서 변수의 자료형으로 정의함
    -- 사용법) 변수명 테이블명.컬럼명%TYPE
    v_ename EMPLOYEE.ENAME%TYPE := UPPER('&p_ename');
    v_sal   EMPLOYEE.SALARY%TYPE;
-- 실행부
BEGIN
    -- 사원명을 입력받아 조회하는 SQL문 : 결과는 v_sal 변수에 저장
    SELECT SALARY INTO v_sal
    FROM EMPLOYEE
    WHERE ENAME = v_ename;
    
    -- 조건문
    IF v_sal >= 3000 THEN
        DBMS_OUTPUT.PUT_LINE('고소득자입니다.');
    ELSIF v_sal >= 2000 THEN
        DBMS_OUTPUT.PUT_LINE('중간 소득자입니다.');
    ELSE
        DBMS_OUTPUT.PUT_LINE('저소득자입니다.');
    END IF;
END;
/

-- 예제 5) 반복문 : 커서
-- 입력값 변수 : p_dno
ACCEPT p_dno PROMPT '부서번호를 입력하세요.'
-- 선언부(정의부)
DECLARE
    -- 커서(2차원배열) : 여러 데이터를 가지고 있는 SELECT 조회문
    -- 커서 정의하는 부분
    -- 사용법)
--           CURSOR 커서변수명 IS
--           SELECT 컬럼명, 컬럼명2, 컬럼명2, ...
--           FROM 테이블명
--           WHERE 조건절;
    CURSOR emp_cursor IS
        SELECT ENAME, SALARY, DNO
        FROM EMPLOYEE
        WHERE DNO = &p_dno;
-- 실행부
BEGIN
    -- FOR문(반복문) == 자바/JS 향상된 FOR문과 비슷
    -- 증감식 없고, 데이터의 끝에 도달하면 반복문 종료
    -- 사용법) FOR 변수명(객체) IN 커서변수명(배열) LOOP
    --              반복문(변수명.컬럼명);
    --        END LOOP;
    FOR emp_record IN emp_cursor LOOP
        -- 차례로 화면에 출력하기
        DBMS_OUTPUT.PUT_LINE(emp_record.ename || ' ' || emp_record.salary
                            || ' ' || emp_record.dno);
    END LOOP;
END;
/

-- (참고) 실무에서 사용하는 이름있는 프로시저 형태
-- 사용법) 
--          CREATE OR REPLACE PROCEDURE 프로시저명
--              (매개변수 in 자료형
--               내보내기변수 out 자료형  -- js return 값과 비슷
--               )
--          IS
--              선언부(정의부)
--          BEGIN
--              실행문;
--          END;
--          /
-- 프로시저 정의 : DB에 소스가 저장됨
CREATE OR REPLACE PROCEDURE pro_ename_sal
(p_ename in employee.ename%type)
IS
-- 선언부
    v_sal employee.salary%type; -- 사원테이블의 급여 자료형을 참조
-- 실행부
BEGIN
    -- 사원명을 받아서 급여 조회 sql
    SELECT SALARY INTO v_sal
    FROM EMPLOYEE
    WHERE ENAME = p_ename;
    -- 화면 출력
    DBMS_OUTPUT.PUT_LINE(v_sal || ' 입니다.');
END;
/
-- 프로시저 실행 (2가지)
-- 사용법) CALL 프로시저명(입력값);
--        EXEC 프로시저명(입력값);
CALL pro_ename_sal('SCOTT');
EXEC pro_ename_sal('SCOTT');

-- 예제 7) 평션 만들기
-- 예제) 부서번호를 매개변수로 받아서 위치를 출력하는 함수 정의
-- 함수(FUNCTION) 특징 : 무조건 RETURN 값이 있음(결과 내보내기가 있음)
-- 사용법)
--          CREATE OR REPLACE FUNCTION 펑션이름
--          (매개변수 in 자료형)
--          RETURN department.loc%type
--          IS
--              선언부(정의)
--          BEGIN
--              실행문;
--              RETURN 결과변수;
--          END;
--          /
CREATE OR REPLACE FUNCTION fn_ename_sal
(p_dno in department.dno%type)
RETURN department.loc%type
IS
-- 선언부
   v_loc department.loc%type; -- 부서테이블의 위치 자료형 참조
-- 실행부
BEGIN
--  부서번호를 매개변수로 받아 위치를 조회하는 SQL문
    SELECT LOC INTO v_loc
    FROM DEPARTMENT
    WHERE DNO = p_dno;
    
    RETURN v_loc;
END;
/

-- 함수 실행 : SELECT 문으로 조회
SELECT fn_ename_sal(10) FROM DUAL;
반응형

'SQL > SQL_이론' 카테고리의 다른 글

SELECT 문  (0) 2024.06.25
WHERE 절  (0) 2024.06.25
VIEW  (0) 2023.09.15
SYSTEM_ROLE  (0) 2023.09.14
시퀀스와 인덱스  (0) 2023.09.14
반응형

VIEW

-- 18_View
-- 뷰(View) : 하나 이상의 테이블이나 다른 뷰를 이용해서 생성하는 가상의 테이블
-- 활용) 1) 보안을 유지하기 위해 사용함 : 사원테이블 - 급여컬럼(비밀로 유지 : 대외비)
--      2) SQL 문을 미리 만들어 놓고 재활용 : 코딩 생산성 향상

VIEW 생성

-- 예제1) 부서테이블과(DEPARTMENT) 사원테이블을(EMPLOYEE) 
--        조인한 결과를 뷰로 만들어서 출력하세요
--  뷰이름 : VW_EMP_COMPLEX
-- 열명은 중복이 안되게 지정

-- 조인
SELECT EMP.*, DEP.DNAME, DEP.LOC
FROM EMPLOYEE EMP, DEPARTMENT DEP
WHERE EMP.DNO = DEP.DNO;

-- 뷰 생성
CREATE OR REPLACE VIEW VM_EMP_COMPLEX
AS
SELECT EMP.*, DEP.DNAME, DEP.LOC
FROM EMPLOYEE EMP, DEPARTMENT DEP
WHERE EMP.DNO = DEP.DNO;

-- 뷰 사용
SELECT * FROM VM_EMP_COMPLEX;

-- 뷰 정보 확인 : 데이터사전(시스템테이블:관리용(미리생성되어 있음) : USER_VIEWS
SELECT * FROM USER_VIEWS;

-- 뷰에 INSERT 가능한가? => 가능
-- 예제 2) VW_EMP_JOB 에 INSERT 하기
-- 뷰 컬럼 :  사번, 사원이름, 부서번호, 담당업무
INSERT INTO VW_EMP_JOB
VALUES(8000, '윤정화', 30, 'SALESMAN');
COMMIT;
SELECT * FROM VW_EMP_JOB;

-- 예제3) 뷰에 그룹함수 써서 만들기
-- 그룹함수 : SUM, AVG, COUNT, MAX, MIN 등
-- 부서별(DNO) 급여합계(SUM(SALARY)), 급여평균(AVG(SALARY))을 
-- 출력하는 SQL문을 뷰로 만드세요
-- 출력 : DNO, SUM(SALARY), AVG(SALARY)
-- 뷰이름 : VW_EMP_SALARY
-- 대상테이블 : EMPLOYEE
-- 힌트 : 컬럼에 별칭을 부여하세요.
--      급여합계 : SAL_SUM
--      급여평균 : SAL_AVG
-- 뷰 생성시 그룹함수는 별명이 필요함
CREATE OR REPLACE VIEW VW_EMP_SALARY
AS
SELECT DNO, SUM(SALARY) AS SAL_SUM, ROUND(AVG(SALARY), 1) AS SAL_AVG
FROM EMPLOYEE
GROUP BY DNO;

SELECT * FROM VW_EMP_SALARY;


-- 그룹함수로 만든 뷰에 INSERT? 불가!
-- 뷰 컬럼 : DNO, SAL_SUM, SAL_AVG
INSERT INTO VW_EMP_SALARY
VALUES(30, 1000, 3000);     -- 에러발생

-- 뷰 삭제(DROP ~)
DROP VIEW VW_EMP_SALARY;

참고사항

-- (참고) 뷰 INSERT 기본 가능(그룹함수가 없을 때)
-- 뷰에 INSERT 기능 제한 : 옵션 추가 => WITH READ ONLY
-- 예제 4) WITH READ ONLY 옵션을 붙여서 뷰 만들기
-- SQL : 직위가 MANAGER 인 사원을 출력하는 뷰 만들기
CREATE OR REPLACE VIEW VW_EMP_JOB_READONLY
AS
SELECT ENO, ENAME, DNO, JOB
FROM EMPLOYEE
WHERE JOB LIKE '%MANAGER%' WITH READ ONLY;

SELECT * FROM VW_EMP_JOB_READONLY;
-- INSERT 테스트
INSERT INTO VW_EMP_JOB_READONLY
VALUES(9000, '김주현', 30, 'MANAGER');

// 오류발생
SQL 오류: ORA-42399: 읽기 전용 뷰에서는 DML 작업을 수행할 수 없습니다.
42399.0000 - "cannot perform a DML operation on a read-only view"

연습문제

-- 19_View_Exam
-- 뷰 연습문제

--— 1) 20번 부서에(DNO) 소속된 사원의 사원번호와(ENO) 
--     이름과(ENAME) 부서번호를(DNO) 출력하는 
--—    VIEW를 정의하시오.(VW_EMP_DNO)
--    대상테이블 : EMPLOYEE
-- 뷰 : SQL 문을 특정 이름으로 정해놓은 가상 테이블
CREATE OR REPLACE VIEW VW_EMP_DNO
AS
SELECT ENO, ENAME, DNO
FROM EMPLOYEE
WHERE DNO = 20;

SELECT * FROM VW_EMP_DNO;

--— 2) 이미 생성되어 있는 상기 뷰에(1번뷰) 대해 급여(SALARY) 
--     역시 출력하도록 수정해서 재생성하세요
-- (VW_EMP_DNO)
--    대상테이블 : EMPLOYEE

CREATE OR REPLACE VIEW VW_EMP_DNO
AS
SELECT ENO, ENAME, DNO, SALARY
FROM EMPLOYEE
WHERE DNO = 20;

SELECT * FROM VW_EMP_DNO;

--— 3) 생성된 뷰를 제거하세요(VW_EMP_DNO)

DROP VIEW VW_EMP_DNO;
반응형

'SQL > SQL_이론' 카테고리의 다른 글

WHERE 절  (0) 2024.06.25
프로시저  (0) 2023.09.15
SYSTEM_ROLE  (0) 2023.09.14
시퀀스와 인덱스  (0) 2023.09.14
TABLE_CONSTRAINT  (0) 2023.09.14
반응형

SYSTEM 계정으로 변경

SYSTEM 계정이 없는 경우

 

-- 16_System_Role
-- 유저만들기(계정생성), 권한주기
-- 1) 유저만들기
-- Oracle DB 생성 : 기본관리자 => SYSYEM 계정(SYS(최고관리자) 등)
-- 예제 1) USERTEST01 유저를 만들고 암호를 pass1 라고 지정하세요.
-- 사용법) CREATE USER 계정명 IDENTIFIED BY 암호;
CREATE USER USERTEST01 IDENTIFIED BY pass1; -- User USERTEST01이(가) 생성되었습니다.

-- 예제 2) 위에서 만든 USERTEST01 유저에 접속 권한을 부여하기
-- 사용법) GRANT CREATE SESSION TO 계정명;
GRANT CREATE SESSION TO USERTEST01; -- Grant을(를) 성공했습니다.

-- 테이블 생성 권한 부여하기
-- 사용법) GRANT CREATE TABLE TO 계정명;
GRANT CREATE TABLE TO USERTEST01; -- Grant을(를) 성공했습니다.

-- 공간에 대한 권한 부여하기(무한) : 테이블(논리공간) -> 물리공간 배정(할당)
-- 사용법) GRANT UNLIMITED TABLESPACE TO 계정명;
GRANT UNLIMITED TABLESPACE TO USERTEST01; -- Grant을(를) 성공했습니다.

 

ROLE

-- 예제 3) 권한들의 집합 == ROLE(롤)
-- 접속 권한들의 모임 == CONNECT 롤
-- 테이블, 인덱스, 함수 등을 사용하는 권한 모임 == RESOURCE 롤
-- VIEW 생성권한이 없음
GRANT CONNECT, RESOURCE, CREATE VIEW TO USERTEST01;
-- 유저 삭제(DROP ~)
-- 사용법) DROP USER 유저명;
DROP USER USERTEST01;

 

계정 테스트

테스트시 상태 : 성공이 나오면 됨!

 

동의어(SYNONYM)

-- 2) 동의어(SYNONYM)
-- 다른 데이터베이스나 다른 계정의 테이블, 인덱스 등의 별명을 붙이는것
-- 예제)
-- 샘플테이블(SYSTEM 계정) : SAMPLETBL
-- 컬럼 : MEMO VARCHAR2(50)
CREATE TABLE SAMPLETBL(
        MEMO VARCHAR2(50)
);

-- 데이터 2건 생성
INSERT INTO SAMPLETBL VALUES('오월은 푸르구나');
INSERT INTO SAMPLETBL VALUES('최선을 다합시다');
COMMIT;
SELECT * FROM SAMPLETBL;

-- SYSTEM 계정의 테이블 -> 권한 부여 : SELECT (조회권한)
-- SELECT 권한 주기
-- 사용법) GRANT SELECT ON 테이블명 TO 계정명;
GRANT SELECT ON SAMPLETBL TO SCOTT;

-- 동의어 생성 권한 : SCOTT
-- 사용법) GRANT CREATE SYNONYM TO 계정명;
GRANT CREATE SYNONYM TO SCOTT;
-----------------------------------------------------------------------------
-- 동의어 실습
-----------------------------------------------------------------------------
-- SCOTT 계정으로 접속
-- SAMPLETBL : SYSTEM 계정이 소유하고 있는 테이블
-- 사용법) SELECT * FROM 계정명.테이블명;
SELECT * FROM SAMPLETBL; -- 에러발생
SELECT * FROM SYSTEM.SAMPLETBL;
-- 위의 경우와 같이 다른 유저의 테이블 조회시 테이블명이 길어짐
-- 동의어(테이블별명) 생성
-- 사용법) CREATE SYNOYM 테이블별명 FOR 계정명.테이블명;
CREATE SYNONYM SAMPLETBL FOR SYSTEM.SAMPLETBL;
-- 조회
SELECT * FROM SAMPLETBL; -- 동의어로 조회됨

-- 동의어 삭제(DROP ~)
DROP SYNONYM SAMPLETBL;

 

반응형

'SQL > SQL_이론' 카테고리의 다른 글

프로시저  (0) 2023.09.15
VIEW  (0) 2023.09.15
시퀀스와 인덱스  (0) 2023.09.14
TABLE_CONSTRAINT  (0) 2023.09.14
TABLE_ALTER  (0) 2023.09.14
반응형

시퀀스

-- 14_Sequence_Index
-- 1. 시퀀스(Sequence) : 호출(실행)할때마다 자동적으로 숫자를 증가시키는것(객체)
-- 목적) 기본키 용도로 사용(중복이 없음, null 없음)
-- 활용 예) 자유게시판 : NO(1 ~ n), 고객: 고객No(1 ~ n)
-- 실무용어 => 채번 : 자동적으로 1씩 증가시키는 값(1 ~ n : 시퀀스 대상)
-- 예제 1) SAMPLE_SEQ 시퀀스를 1부터 시작해서 10씩 증가시키는 시퀀스를 만드세요

-- 사용법 )
--          CREATE SEQUENCE 시퀀스명
--          INCREMENT BY    증가값
--          START WITH      시작값
--          MINVALUE        최소값
--          MAXVALUE        최대값

CREATE SEQUENCE SAMPLE_SEQ
INCREMENT BY 10
START WITH 1;

-- 사용법) 
-- 1) 시퀀스명.NEXTVAL : 시퀀스가 증가함
SELECT SAMPLE_SEQ.NEXTVAL FROM DUAL;

-- 현재 증가된 시퀀스의 값을 확인 : 최초 1번은 시퀀스명.NEXTVAL 실행 후 확인가능
-- 사용법)
-- SAMPLE_SEQ.CURRVAL
SELECT SAMPLE_SEQ.CURRVAL FROM DUAL;

-- 시스템 테이블들 : 시퀀스 확인용 테이블(뷰) : 데이터사전(DICTIONARY VIEW)
SELECT SEQUENCE_NAME
        ,MIN_VALUE
        ,MAX_VALUE
        ,INCREMENT_BY
FROM USER_SEQUENCES;

-- 예제 2) 임시테이블에 시퀀스 INSERT 하기
-- 임시테이블(구조만 복사): 부서(DEPARTMENT) -> (복사) DEPT_TEMP
CREATE TABLE DEPT_TEMP
AS
SELECT * FROM DEPARTMENT
WHERE 1=2;
-- 조회
SELECT * FROM DEPT_TEMP;
-- 시퀀스 INSERT : 대상 컬럼 : 시퀀스명.NEXTVAL (DNO: 부서번호)

-- 시퀀스 삭제
-- 사용법 ) DROP SEQUENCE 시퀀스명
DROP SEQUENCE SAMPLE_SEQ;

-- 시퀀스 생성
CREATE SEQUENCE SAMPLE_SEQ
INCREMENT BY 10
START WITH 1; -- 생성(10씩 증가)

-- INSERT 문 정의
INSERT INTO DEPT_TEMP
VALUES(SAMPLE_SEQ.NEXTVAL, 'ACCOUNTING', 'NEW YORK');

SELECT * FROM DEPT_TEMP;

-- 영구반영
COMMIT;

 

인덱스

-- 2. 인덱스( INDEX )
-- 사용) 컬럼에 인덱스를 지정하여 사용함
-- 목적) 조회속도 향상을 위해 조건에 해당하는 컬럼에 인덱스를 생성(지정)함
-- 기본키(PK) : 중복방지 + NULL값 방지 + 자동인덱스 생성

-- 예제3) 사이트에서 조회시 이름검색(ENAME)이 많은데, 속도가 느리다고 한다. (EMPLOYEE)
-- 해결) ENAME 컬럼에 인덱스 생성 -> 조회속도 향상
-- 명명법) IX_테이블명_컬럼명, IDX_테이블명_컬럼명 
-- 사용법) CREATE INDEX 인덱스이름 ON 테이블명(컬럼명);
CREATE INDEX IX_EMPLOYEE_ENAME ON EMPLOYEE(ENAME);

-- 속도 느린 대상 SQL문
SELECT * FROM EMPLOYEE
WHERE ENAME LIKE 'SCOTT%'; -- 이 부분이 INDEX 를 만들 곳

-- 데이터 사전 : USER_IND_COLUMNS 뷰에서 확인
SELECT INDEX_NAME, TABLE_NAME, COLUMN_NAME
FROM USER_IND_COLUMNS
WHERE TABLE_NAME IN ('EMPLOYEE','DEPARTMENT');

툴에서 확인가능

-- 인덱스 삭제하기(DROP ~)
-- 사용법) DROP INDEX 인덱스명;
DROP INDEX IX_EMPLOYEE_ENAME;

-- *인덱스를 만들어야 하는 기준
-- 1) 테이블의 행의 개수가 많을 경우(데이터 건수가 많을경우)
--    : 10만건 이상
-- 2) WHERE(조건절)에 해당 컬림이 많이 등장할 경우
-- 3) 테이블 조인의 공통컬럼으로 사용될 경우

 

-- 특수 인덱스
-- 1) 결합 인덱스 : 컬럼 여러개를 묶어서 한번에 인덱스로 지정
-- 예) 아래 쿼리문 조회속도가 느릴 때
SELECT * FROM DEPARTMENT
WHERE DNAME = 'SALES'
AND   LOC   = 'NEW YORK';

-- 결합 인덱스 만들기
-- 사용법) CREATE INDEX 인덱스명 ON 테이블명(컬럼1, 컬럼2, ...);
CREATE INDEX IX_DEPT_COM ON DEPARTMENT(DNAME, LOC);

-- 2) 함수 인덱스 : 함수에 인덱스 걸기
SELECT * FROM EMPLOYEE
WHERE SALARY = SALARY * 12;
-- 함수 인덱스(수식인덱스)
-- 사용법) CREATE INDEX 인덱스명 ON 테이블명(수식);
CREATE INDEX IX_EMP_ANNSAL ON EMPLOYEE(SALARY * 12);

 

반응형

'SQL > SQL_이론' 카테고리의 다른 글

VIEW  (0) 2023.09.15
SYSTEM_ROLE  (0) 2023.09.14
TABLE_CONSTRAINT  (0) 2023.09.14
TABLE_ALTER  (0) 2023.09.14
TABLE_CUD  (0) 2023.09.14
반응형

✔ 테이블 제약조건

테이블에 입력될 값을 제한하는 것 제약조건은 컬럼별로 각각 지정할 수 있음

UNIQUE 제약조건 유일한 값만 입력될 수 있음(데이터 중복 금지), NULL 값은 허용
CREATE TABLE 테이블명(컬럼명 자료형(크기) 제약조건이름);

 

-- 1) UNIQUE 제약조건 : 유일한 값만 입력될 수 있음(데이터 중복 금지), NULL 값은 허용
-- 추가) NOT NULL 제약조건(*) : NULL 값이 입력될 수 없음
-- 예제 1) CUSTOMER 테이블을 정의하고 ID 컬럼에 UNIQUE 제약조건을 지정하세요
-- (ID          VARCHAR2(20) --> UNIQUE 제약조건 지정
-- (PWD         VARCHAR2(20)
-- (NAME        VARCHAR2(20)
-- (PHONE       VARCHAR2(30)
-- (ADDRESS     VARCHAR2(1000)

CREATE TABLE CUSTOMER(
    ID          VARCHAR2(20) UNIQUE,
    PWD         VARCHAR2(20) NOT NULL,
    NAME        VARCHAR2(20) NOT NULL,
    PHONE       VARCHAR2(30),
    ADDRESS     VARCHAR2(1000)
);

 

✔ 기본키 제약조건

CREATE TABLE 테이블명(컬럼명 자료형(크기), CONSTRAINT 제약조건이름 PRIMARY KEY (컬럼명));
-- 기본키의 특징 : 유일한 값만 입력되고(중복방지) + NOT NULL 제약조건포함 + (참고 : INDEX 자동생성)
-- 특징) 주로 테이블 설계시 1개의 테이블당 거의 1개는 기본키가 존재함
-- 기본키 제약조건에 이름을 부여 : CONSTRAINT 제약조건이름 제약조건
-- 제약조건이름 붙이기 약속(명명법) : PK_테이블명_컬럼명
-- 사용법) CREATE TABLE 테이블명(컬럼명 자료형(크기), CONSTRAINT 제약조건이름 PRIMARY KEY(컬럼명));

CREATE TABLE CUSTOMER2(
    ID          VARCHAR2(20),
    PWD         VARCHAR2(20) NOT NULL,
    NAME        VARCHAR2(20) NOT NULL,
    PHONE       VARCHAR2(30),
    ADDRESS     VARCHAR2(1000),
    CONSTRAINT PK_CUSTOMER2_ID PRIMARY KEY(ID) -- ID컬럼에 기본키 제약조건을 건다 제약조건이름은 PK_CUSTOMER_ID

SELECT * FROM CUSTOMER2; -- 조회
-- INSERT 테스트 : 기본키(유일성 + NOT NULL 지정)
INSERT INTO CUSTOMER2 VALUES(NULL, NULL, NULL, '010-123-4567', 'SEOUL'); -- 기본키로 인해 에러발생

 

✔ 외래키 제약조건

CONSTRAINT FK_테이블명_컬럼명 REFERENCES 부모테이블
-- 3) 외래키(참조키) 제약조건 : FOREIGN KEY(FK)
-- 무결성 제약조건 : 기본키 / 외래키(참조키) 
-- 무결성 의미 : 데이터에 결점이 없는 것
-- 기본키 : 회원의 ID (중복되면 안됨 + NULL 입력되어도 안됨)
-- 참조키 : 부서테이블의 부서번호(DNO : 10 ~ 40), 사원테이블의 부서번호(DNO : 10 ~ 30) 있을때
--         부서테이블의 부서번호 값만 사원테이블의 부서번호에 INSERT 할 수 있음(참조 무결성)
--         만약 부서번호에 50번이 들어간다면 참조 무결성이 깨진 것
-- 사용법) CREATE TABLE 테이블명 (
--                    컬럼명 자료형(크기) CONSTRAINT 제약조건이름 PRIMARY KEY
--                    컬럼명 자료형(크기) CONSTRAINT 제약조건이름 REFERENCES 부모테이블명);
-- 예제3) EMP_SECOND 테이블을 만들고, 
--        ENO NUMBER(4) (기본키)
--        ENAME VARCHAR2(10)
--        JOB VARCHAR2(9)
--        DNO NUMBER(2) (참조키)
-- 지정하세요

CREATE TABLE EMP_SECOND(
    ENO NUMBER(4) CONSTRAINT PK_EMP_SECOND_ENO PRIMARY KEY      -- 기본키 지정
    ,ENAME VARCHAR2(10)
    ,JOB VARCHAR2(9)
    ,DNO NUMBER(2) CONSTRAINT FK_EMP_SECOND_DNO REFERENCES DEPARTMENT   -- 참조키 지정
);

 

✔  CHECK 제약조건

CONSTRAINT CK_EMP_SECOND_SALARY CHECK (조건)
-- 예제 4) EMP_SECOND 테이블에 CHECK 제약조건을 지정하세요 (SALARY>0 값만 INSERT 될 수 있도록)
CREATE TABLE EMP_SECOND(
    ENO NUMBER(4) CONSTRAINT PK_EMP_SECOND_ENO PRIMARY KEY
    ,ENAME VARCHAR2(10)
    ,SALARY NUMBER(7,2) CONSTRAINT CK_EMP_SECOND_SALARY CHECK(SALARY > 0)
);

-- CHECK 제약조건 테스트
INSERT INTO EMP_SECOND VALUES(8000, '윤정화', -200);

 

✔  DEFAULT 제약조건

-- 예제 5)
CREATE TABLE EMP_SECOND(
    ENO NUMBER(4) CONSTRAINT PK_EMP_SECOND_ENO PRIMARY KEY
    ,ENAME VARCHAR2(10)
    ,SALARY NUMBER(7,2) DEFAULT 1000
);


INSERT INTO EMP_SECOND(ENO, ENAME) VALUES(8000, '윤정화'); -- SALARY 값 미지정
COMMIT;
SELECT * FROM EMP_SECOND;

 

✔  기타 제약조건

-- 기타사항 : 제약조건
-- 테이블 복사 : CREATE TABLE ~ AS SELECT ~
-- 제약조건 복사안됨(제약조건 추가 생성작업 : 기본키/참조키)

-- 참고) 시스템용 테이블 또는 뷰(VIEW): DB 관리용 테이블
-- 용도) 현재 생성된 테이블의 정보, 제약조건, 크기 등을 확인하는 용도
-- 테이블 정보(제약조건) : USER_CONSTRAINTS
-- 원본테이블 제약조건 확인
SELECT TABLE_NAME, CONSTRAINT_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME IN ('EMPLOYEE', 'DEPARTMENT')
ORDER BY TABLE_NAME;
-- 복사본테이블 제약조건 확인
SELECT TABLE_NAME, CONSTRAINT_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME IN ('EMP_COPY', 'DEPT_COPY')
ORDER BY TABLE_NAME;

 

✔  테이블 생성 후 제약조건 추가/변경/제거하기

-- 예제 1) 사원복사본 테이블(EMP_COPY)에 기본키(PRIMARY KEY) 추가하기
-- 사용법) ALTER TABLE 테이블명
--        ADD CONSTRAINT PK_테이블명_컬럼명 PRIMARY KEY(컬럼명);
-- ENO : 사원번호에 기본키 추가
ALTER TABLE EMP_COPY
ADD CONSTRAINT PK_EMP_COPY_ENO PRIMARY KEY(ENO);

-- 예제2) 부서복사본(DEPT_COPY) 테이블에 기본키(PK) 추가하기
-- 기본키 : DNO(부서번호),(테이블의 데이터 중에서 유일한 값을 가져야 되는것)
ALTER TABLE DEPT_COPY
ADD CONSTRAINT PK_DEPT_COPY_DNO PRIMARY KEY(DNO);

-- 예제3) 테이블 생성 후에 외래키(참조키:FK) 추가하기 : EMP_COPY
-- 자식테이블에 추가 (부서테이블(부모): DEPT_COPY, 사원테이블(자식): EMP_COPY )
ALTER TABLE EMP_COPY
ADD CONSTRAINT FK_EMP_COPY_DNO
FOREIGN KEY(DNO) REFERENCES DEPT_COPY(DNO);

 

-- 예제4) 테이블 생성 후에 제약조건 삭제하기
-- 부모테이블(부서: 부서번호)의 기본키 <-> 자식테이블의 참조키(사원: 부서번호)
-- 부모테이블의 기본키 삭제하기 : 강제삭제하기 옵션(CASCADE)
-- CASCADE : 자식테이블에 있는 외래키도 같이 삭제됨
ALTER TABLE DEPT_COPY
DROP PRIMARY KEY; -- 자식테이블에 참조키가 걸려있으면 오류발생

ALTER TABLE DEPT_COPY
DROP PRIMARY KEY CASCADE;

 

-- 예제5) 제약조건 변경하기
-- EMP_COPY(사원) : ENAME (NULL 허용) -> ENAME NOT NULL 제약조건으로 변경

ALTER TABLE EMP_COPY
MODIFY ENAME CONSTRAINT NN_EMP_COPY_ENAME NOT NULL;

-- 제약조건이름으로 제약조건 삭제하기
ALTER TABLE EMP_COPY
DROP CONSTRAINT NN_EMP_COPY_ENAME;

 

✔  연습문제

-- 13_Table_Constraint_Exam
-- 제약조건 연습문제
--— 1) EMPLOYEE 테이블의 구조를 복사하여 EMP_SAMPLE 란 
--     이름의 테이블을 만드시오.
--—   사원 테이블의 사원번호 컬럼(ENO)에 
--     테이블 레벨로 PRIMARY KEY 제약조건을 지정하되,
--—   제약 조건 이름은 PK_MY_EMP 하시오.
-- 1) 복사본 : 제약조건 복사 안됨(기본키,외래키 직접 생성해야 함)

-- 테이블 구조복사
CREATE TABLE EMP_SAMPLE
AS
SELECT * FROM EMPLOYEE
WHERE 1=2;

-- ENO에 PRIMARY KEY 제약조건 지정
ALTER TABLE EMP_SAMPLE
ADD CONSTRAINT PK_MY_EMP PRIMARY KEY(ENO);

--— 2) DEPARTMENT 테이블의 구조를 복사하여 
--     DEPT_SAMPLE란 이름의 테이블을 만드시오.
--—   부서번호 컬럼(DNO)에 PRIMARY KEY 제약조건을 지정하되,
--—   제약 조건 이름은 PK_MY_DEPT 하시오.

-- 테이블 구조복사
CREATE TABLE DEPT_SAMPLE
AS
SELECT * FROM DEPARTMENT
WHERE 1=2;

-- DNO에 PRIMARY KEY 제약조건 지정
ALTER TABLE DEPT_SAMPLE
ADD CONSTRAINT PK_MY_DEPT PRIMARY KEY(DNO);

--— 3) 사원 테이블의(EMP_SAMPLE) 부서번호 컬럼에 존재하지 않는 
--      부서의 사원이 배정되지 않도록
--—    외래 키(FOREIGN KEY:FK) 제약조건을 지정하되, 
--   FK_MY_DEPT_EMP 로 하시오.
--— 참조테이블 : DEPARTMENT (데이터가 있음)
--— 참조키,외래키(FOREIGN KEY:FK)


-- DNO 컬럼에 외래키 지정

ALTER TABLE EMP_SAMPLE
ADD CONSTRAINT FK_MY_DEPT_EMP
FOREIGN KEY(DNO) REFERENCES DEPARTMENT(DNO);


SELECT TABLE_NAME, CONSTRAINT_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME IN ('EMP_SAMPLE', 'DEPT_SAMPLE')
ORDER BY TABLE_NAME;
반응형

'SQL > SQL_이론' 카테고리의 다른 글

SYSTEM_ROLE  (0) 2023.09.14
시퀀스와 인덱스  (0) 2023.09.14
TABLE_ALTER  (0) 2023.09.14
TABLE_CUD  (0) 2023.09.14
SUBQUERY  (0) 2023.09.14

+ Recent posts