임용/데이터베이스

Chapter 06 SQL

뚜비히히 2023. 4. 17. 19:28
  • SQL(Structured Query Language) 데이터 언어는 원래 1974년에 IBM 연구소에서 발표한 SEQUEL(Structred English QUEry Language)에 연유한다. 
  • IBM은 처음 이 언어를 실험적 관계 데이터베이스 시스템, 'SYSTEM R'의 인터페이스로 설계 구현하였다.
  • SQL의 의미는 구조화 질의어지만 단순히 검색만을 위한 데이터 질의어가 아니라 종합 데이터베이스 언어 역할을 한다. 즉, 데이터 정의어(DDL), 데이터 조작어(DML) 그리고 데이터 제어어(DCL)의 기능을 모두 제공하고 있다.
  • SQL의 특징은 온라인 터미널을 통해 대화식 질의어를 사용하는 것은 물론이고 Java, COBOL, C, C++ 등과 같은 범용 프로그래밍 언어로 쓰여진 응용 프로그램에 삽입된 형태로도 사용이 가능하다는 것이다. 
  • SQL은 개개의 레코드 단위로 처리하기 보다는 레코드 집합 단위로 처리하며 SQL 명령문에는 데이터 처리를 위한 접근 경로(access path)에 대한 명세가 필요하지 않으므로 선언적 언어라고 할 수 있다. 
  • 한 가지 유의할 것은 SQL은 릴레이션(relation), 튜플(tuple), 애트리뷰트(attribute)와 같은 관계 모델의 공식적 용어 대신 이에 대응하는 테이블(table), 행(row), 열(column)과 같은 일반적인 용어를 사용하고 있다.

 

6.1 SQL 데이터 정의문

6.1.1 스키마 카탈로그

  • SQL2에서는 SQL 스키마 개념을 도입했는데 이것은 하나의 응용(사용자)에 속하는 테이블과 기타 구성 요소들을 그룹 짓기 위한 것이다. 
  • SQL 스키마는 스키마 이름(schema name)으로 식별되는데 그 스키마의 소유자나 계정을 나타내는 허가권자(authorization identifier)와 그 스키마의 각 요소에 대한 기술자(descriptor)를 포함한다.
  • 스키마 요소에는 테이블, 뷰, 도메인, 그리고 기타 허가권이나 무결성 등에 관한 요소들이 있다. 
  • 예를 들어, 다음 명령문은 이름이 UNIVERSITY이고 허가권자가 SHLEE인 스키마를 생성한다.
CREATE SCHEMA UNIVERSITY AUTHORIZATION SHLEE;
  • 아무나 스키마 요소를 생성할 수 있는 것은 아니다. 시스템 관리자나 DBA를 통해 권한이 부여된 사용자만 이런 권한을 갖게 된다. 
  • SQL은 스키마 개념과 더불어 카탈로그 개념도 정의하고 있는데 여기서의 카탈로그는 한 SQL 시스템 내애서의 스키마들의 집합을 말한다. 
  • 각 카탈로그는 반드시 INFORMATION_SCHEMA라고 하는 특별한 스키마를 포함하게 되어 있는데 이것은 그 카탈로그에 포함되어 있는 모든 스키마들에 대한 정보와 이 스키마들에 있는 모든 요소들에 대한 정보를 제공하기 위한 것이다. 

6.1.2 정의문

  • SQL 도메인을 정의하기 위한 명령문 형식은 다음과 같다.
CREATE DOMAIN 도메인_이름 데이터_타입
		[기정_값_정의]
    		[도메인_제약조건_정의리스트]
  • "[ ]"로 묶여진 것은 생략할 수 있는 부분을 나타낸다.

 

  • 다음은 DEPT라는 이름의 도메인 정의문의 예이다.
CREATE DOMAIN DEPT CHAR(4)
	DEFAULT '???'
	CONSTRAINT VALID-DEPT
	CHECK(VALUE IN ('COMP', 'ME', 'EE', 'ARCH', '???'));
  • 일단 정의된 도메인은 ALTER DOMAIN 명령문으로 어느 때고 변경시킬 수 있다. 

 

  • 일단 만들어진 도메인은 다음과 같이 DROP DOMAIN 명령문으로 삭제할 수도 있다.
DROP DOMAIN 도메인_이름 옵션;
  • 여기 옵션에는 RESTRICT나 CASCADE가 있다. 만일 RESTRICT로 명세 되면 이 도메인을 참조하고 있는 곳이 없을 때만 삭제된다. 만일 CASCADE로 명세 되면 이 도메인을 참조하고 있는 뷰나 제약조건도 함께 삭제되지만 참조 열(referencing column)은 삭제되지 않고 다른 형태의 데이터 타입으로 변경된다.

6.1.3 기본 테이블 생성

  • 기본 테이블(base table)은 CREATE TABLE 문으로 만들어지는 테이블로서 독자적으로 존재하는 테이블이다. 
  • 테이블과 행(튜플)들이 DBMS에 의해 하나의 파일로 저장된다는 의미이다. 
  • 가상 테이블(virtal table)은 CREATE VIEW 문으로 만들어지는 테이블로서 독자적으로 존재하지 못하고 궁극적으로 어떤 기본 테이블로부터 유도되어 만들어지는 테이블이다. 
  • 임시 테이블(temporary table)은 어떤 DDL문으로 만들어지는 것이 아니고 질의문 처리 과정의 중간 결과로 만들어지는 테이블을 말한다. 
  • 기본 테이블을 정의하기 위한 정의문의 형식은 다음과 같다.
CREATE TABLE 기본테이블
	({열_이름 데이터_타입 [NOT NULL] [DEFAULT 값],}+
        [PRIMARY KEY (열_이름_리스트),]
        {[UNIQUE (열_이름_리스트),]}+
        {[FOREIGN KEY(열_이름_리스트)
       		REFERENCES 기본테이블[(열_이름_리스트)]
                [ON DELETE 옵션]
                [ON UPDATE 옵션],]}*
                [CONSTRAINT 이름] [CHECK(조건식)]);
  • PRIMARY KEY : 기본키와 개체 무결성 제약조건을 명세
  • UNIQUE : 대체 키를 명세, 후보키
  • NOT NULL : 애트리뷰트 값 제약조건
  • FOREIGN KEY : 외래 키와 참조무결성 제약조건을 명세
    → SQL에서 참조된 테이블의 후보 키도 외래키로 될 있다. 
  • 옵션에는 SET NULL, SET DEFAULT, CASCADE가 있다.
    • ON DELETE SET NULL : 참조 튜플(열 값)이 삭제되면 NULL로 설정
    • ON UPDATE CASCADE : 참조 튜플(열 값)이 갱신되면 갱신된 값이 파급적으로 갱신됨
    • CHECK : 제약조건을 명세 

6.1.4 기본 테이블의 제거와 변경

  • 정의된 기존의 기본 테이블은 DROP TABLE 명령문으로 어느 때고 삭제할 수 있다. 삭제를 할 때에는 CASCADE나 RESTRICT 중의 어느 하나가 명세 되어야 한다. 예를 들어, COURSE 테이블을 삭제하는 명령문은 다음과 같다.
DROP TABLE 기본_테이블_이름{RESTRICT|CASCADE};
DROP TABLE COURSE CASCADE;
  •  이렇게 CASCADE가 명세된 명령이 실행되면 COURSE 테이블을 참조하는 다른 뷰 정의나 제약조건이 있으면 이들도 함께 자동으로 삭제된다. 
  • 만약 RESTRICT가 명세 되었다면 이 테이블이 다른 뷰 정의에서나 제약조건에서 참조되고 있는 경우에는 실행되지 않는다. 

 

  • 기존의 스키마도 DROP SCHEMA 명령문으로 삭제할 수 있다. 이때 CASCADE나 RESTRICT가 명세될 수도 있는데 CASCADE가 명세되면 이 스키마뿐만 아니라 연관된 객체들도 모두 삭제된다. 그러나 RESTRICT가 명세되면 스키마가 공백인 경우에만 삭제된다.
DROP SCHEMA 스키마_이름 {RESTRICT|CASCADE};
DROP SCHEMA UNIVERSITY CASCADE;

 

  • 기존의 기본 테이블은 ALTER TABLE 명령문으로 어느 때고 변경할 수 있다. 
ALTER TABLE 기본_테이블_이름
		([ADD 열_이름_데이터_타입][DEFAULT 기정값][DROP 열_이름]
           	 [CASCADE][ALTER 열_이름(DROP DEFAULT|SET DEFALT 기정값)]);
            
ALTER TABLE ENROL
			ADD Final CHAR DEFAULT 'F';

 

  • 기존의 테이블에서 열을 삭제할 때는 DROP문을 CASCADE나 RESTRICT와 함께 명세하면 된다. 
  • 다음 명령문은 ENROL 테이블에서 Grade 열을 삭제시키는 명령문의 예이다.
ALTER TABLE ENROL DROP Grade CASCADE;

 

  • RESTRICT로 명세된 경우에 이 열을 뷰 정의에서나 제약조건에서 참조하고 있다면 실행되지 못한다. 대신 CASCADE로 명세되면 이 열을 참조하는 뷰 정의나 제약조건도 함께 삭제된다.
  • 기정 값을 변경하는 명령문의 예이다.
ALTER TABLE ENROL ALTER Grade DROP DEFAULT;
ALTER TABLE ENROL ALTER Grade SET DEFALT '0';

 

  • 기존에 명세한 무결성 제약 조건을 삭제할 때에도 DROP 문을 사용할 수 있는데 이런 경우에는 삭제할 제약 조건의 이름을 명세할 수 있도록 미리 제약조건에 이름이 정의되어 있어야 한다. 
DROP CONSTRAINT 이름

6.2 SQL 데이터 조작문

대학(UNIVERSTIY) 관계 데이터베이스


6.2.1 데이터 검색 

SQL 검색문의 기본적인 구조

SELECT	열_리스트
FROM	테이블_리스트
WHERE	조건

 

예를 들어, '컴퓨터과 학생의 이름(Sname)과 학번(Sno)을 검색하라.'는 검색문은 다음과 같이 표현한다.

SELECT	Sname, Sno
FROM	STUDENT
WHERE	Dept = '컴퓨터';

 

이 검색문의 실행 결과는 다음과 같이 된다. 

  • 기존의 테이블을 처리하면 또 다른 테이블이 만들어지는 것이다. 이런 성질을 가진 시스템은 폐쇄 시스템(closed system)이라 한다. 
SELECT	STUDENT.Sname, STUDENT.Sno
FROM	STUDENT	
WHERE	STUDENT.Dept = '컴퓨터';

이 예는 앞에 기술한 검색 문과 동일하다.

  • SQL은 한 테이블 내에 똑같은 레코드(행)가 중복될 수 있다. 즉, SQL의 테이블은 일반적으로 기본 키를 반드시 갖아야 하는 것은 아니다. 따라서 이론상 SQL의 테이블은 튜플의 집합이 아니다. 
  • SQL의 테이블은 같은 원소의 중복을 허용하는 다중 집합(multiset) 또는 백(bag)이다.
  • 집합과 같은 결과를 만들기 위해서는 SELECT문에 DISTINCT를 명세해야 된다. 이 DISTINCT를 명세하지 않으면 ALL을 명세한 것과 같이 중복된 레코드가 나타나더라도 제거되지 않는다. 
  • SQL 검색문의 일반적인 형식은 다음과 같다. 
SELECT [ALL|DISTINCT] 열_리스트
FROM 테이블_리스트
[WHERE 조건]
[GROUP BY 열_리스트
[HAVING 조건]]
[ORDER BY 열_리스트 [ASC|DESC]];

 

성질

(1) 검색 결과에 중복 레코드의 제거

[질의] 학생(STUDENT) 테이블에 어떤 학과(Dept)들이 있는지 검색하라.

SELECT DISTINCT Dept
FROM STUDENT;

결과 :

(2) 테이블의 열 전부를 검색하는 경우

[질의] 학생(STUDENT) 테이블 전부를 검색하라

SELECT *
FROM STUDENT;

테이블 전체를 검색할 때는 열 이름을 일일이 전부 나열할 필요 없이 *(asterisk)로 표시하면 된다. 

다음 검색문과 위의 검색문은 동등하다. 

SELECT Sno, Sname, Year, Dept
FROM STUDENT;

결과 : 현재의 학생(STUDENT) 테이블 전체 튜플

Sno Sname Year Dept
100 나수영 4 컴퓨터
200 이찬수 3 전기
300 정기태 1 컴퓨터
400 송병길 4 컴퓨터
500 박종화 2 산공

(3) 조건 검색

[질의] 학생(STUDENT) 테이블에서 학과(Dept)가 '컴퓨터'이고 학년(Year)이 4인 학생의 학번(Sno)과 이름(Sname)을 검색하라

SELECT Sno, Sname
FROM STUDENT
WHERE Dept='컴퓨터' AND Year=4;

결과 : 

Sno Sname
100 나수영
500 박종화

 

(4) 순서를 명세하는 검색

[질의] 등록(ENROL) 테이블에서 중간 성적(Midterm)이 90점 이상인 학생의 학번(Sno)과 과목 번호(Cno)를 검색하되 학번(Sno)에 대해서는 내림차순으로 또 같은 학번에 대해서는 과목 번호(Cno)의 오름차순으로 검색하라.

SELECT Sno, Cno
FROM ENROL
WHERE Midterm ≥ 90
ORDER BY Sno DESC, Cno ASC;

결과 : 

Sno Cno
400 C312
400 C324
300 C312
300 C413
100 C413
100 E412
  • 사용자가 검색 결과의 순서를 오름차순(ASC)이나 내림차순(DESC)을 명세할 수 있다. 

(5) 산술식, 문자 스트링, 새로운 열 이름이 명세된 검색

[질의] 등록(ENROL) 테이블에서 과목 번호(Cno)가 'C312'인 중간 성적(Midterm)에 3점을 더한 점수를 '학번', '중간성적 ='이란 텍스트를 내용 '시험', 그리고 '점수'라는 열 이름으로 검색하라. 

SELECT Sno AS 학번, '중간시험 =' AS 시험, Midterm+3 AS 점수
FROM ENROL
WHERE Cno = 'C312';

결과 : 

학번 시험 점수
300 중간 시험 = 93
400 중간 시험 = 93
500 중간 시험 =  88

 

(6) 복수 테이블로부터의 검색

[질의] 과목 번호(Cno) 'C413'에 등록한 학생의 이름(Sname), 학과(Dept), 성적(Grade)을 검색하라.

SELECT S.Sname, S.Dept, E.Grade
FROM STUDENT S, ENROL E
WHERE S.Sno = E.Sno AND E.Cno = 'C413';

결과 :

Sname Dept Grade
나수영 컴퓨터 A
정기태 컴퓨터 A
송병길 컴퓨터 B

 

(7) 자기 자신의 테이블에 조인하는 검색

[질의] 같은 학과 학생들의 학번을 쌍으로 검색하라. 단, 첫번째 학번은 두 번째 학번보다 작게 하라.

SELECT 	S1.Sno, S2.Sno
FROM	STUDENT S1, STUDENT S2
WHERE	S1.Dept=S2.Dept
	AND S1.Sno < S2.Sno;

결과 :

Sno Sno
100 300
100 400
300 400

 

(8) 집계 함수를 이용한 검색

  • COUNT : 값으 개수
  • SUM : 값의 총계
  • AVG : 평균 값
  • MAX : 최대 값
  • MIN : 최소 값

[질의] 학생 테이블에 학생 수가 얼마인가를 검색하라.

SELECT COUNT(*) AS 학생수
FROM STUDENT;

결과 : 

학생수
5

 

(9) GROUP BY를 이용한 검색

[질의] 과목별 기말 성적(Final)의 평균을 검색하라.

SELECT Cno, AVG(Final) AS 기말평균
FROM ENROL
GROUP BY Cno;

결과 :

Cno 기말평균
C413 90
E412 85
C123 80
C312 90
C324 82

(10) HAVING을 사용한 검색

[질의] 3명 이상 등록한 과목의 기말 평균 성적을 검색하라.

SELECT Cno, AVG(Final) AS 평균
FROM ENROL
GROUP BY Cno
HAVING COUNT(*) ≥ 3;

결과 :

Cno 평균
C413 90
C312 90

 

(11) 부속 질의문(Subquery)을 사용한 검색

[질의] 과목 번호(Cno) 'C413' 등록한 학생 이름(Sname)을 검색하라

SELECT Sname
FROM STUDENT
WHERE Sno IN
	(SELECT Sno
   	 FROM ENROL
   	 WHERE Cno='C413');

결과 :

Sname
나수영
정기태
송병길
  • 부속 질의문(subquery)은 다른 질의문에 중첩(nested)되어 사용되는 검색문으로서 SELECT-FROM-WHERE-GROUP BY-HAVING의 형태를 취한다.
  • 부속 질의문을 포함하고 있는 질의문을 중첩 질의문(nested query)이라 한다.
  • IN은 집합의 멤버십 연산자(∈)로 해석할 수 있다. 
SELECT Sname
FROM STUDENT
WHERE Sno IN(100, 300, 400);

위 원래의 질의문은 조인 연산을 사용하는 질의문으로 표현할 수도 있다.

SELECT STUDENET.Sname
FROM STUDENT, ENROL
WHERE STUDENT.Sno = ENROL.Sno
	AND ENROL.Cno = 'C413';

 

(12) LIKE를 사용하는 검색

[질의] 과목번호(Cno)가 C로 시작하는 과목 번호와 과목이름(Cname)을 검색하라

SELECT Cno, Cname
FROM COURSE
WHERE Cno LIKE 'C%';

결과 : 

Cno Cname
C123 프로그래밍
C312 자료구조
C324 파일구조
C413 데이터베이스
  • LIKR 프레디킷은 서브 스트링 패턴(substring pattern)을 비교하는 비교 연산자로 사용된다.
  • 이 예에서 사용된 %는 서브 스트링 패턴을 명세하는 것으로 'C'로 시작하기만 하면 어떤 길이의 어떤 문자 스트링도 관계없다는 뜻이다. 

 

(13) NULL을 사용한 검색

[질의] 학과(Dept)가 NULL인 학생의 학번과 이름을 검색하라.

SELECT Sno, Sname
FROM STUDENT
WHERE Dept IS NULL;

결과 :

Sno Sname
600 김길동

 

(14) EXISTS를 사용하는 검색

[질의] 과목 'C413'에 등록한 학생의 이름을 검색하라.

SELECT Sname
FROM STUDENT
WHERE EXISTS
	(SELECT *
   	 FROM ENROL
  	   WHERE Sno = STUDENT.Sno AND Cno = 'C413');

결과 :

Sname
나수영
정기태
송병길
  • EXISTS는 존재 정량자(existential quantifier)로서 EXISTS 다음에 나오는 검색문의 실행 결과로 검색된 튜플이 존재하는가를 검사한다. 따라서 이 부속 질의분은 EXISTS(SELECT * FROM) 검색문을 실행한 뒤 그 결과가 공집합이 아니면 참이 되고, 공집합이면 거짓으로 된다.

 

[질의] 과목 'C413'에 등록하지 않은 학생의 이름을 검색하라.

SELECT Sname
FROM STUDENT
WHERE NOT EXISTS
	(SELECT *
   	 FROM ENROL
   	 WHERE Sno = STUDENT.Sno
    		AND Cno='C413';

결과 : 

Sname
이찬수
박종화

 

(15) UNION이 관련된 검색

[질의] 3학년이거나 또는 과목 'C324'에 등록한 학생의 학번을 검색하라

SELECT Sno
FROM STUDENT
WHERE Year=3
UNION
SELECT Sno
FROM ENROL
WHERE Cno='C324';

결과 : 

Sno
200
300
400

UNION은 일반 집합론의 합집합과 같다. 따라서 UNION이 사용되면 결과 테이블에서 중복되는 튜플은 제거된다. 


6.2.2 데이터의 갱신

기존 레코드 열의 값을 변경하기 위해서는 다음과 같은 UPDATE 명령문을 사용한다.

UPDATE 테이블
SET {열_이름 = 산술식}'+
[WHERE 조건];

(1) 하나의 레코드 변경

[질의] 학번이 300인 학생의 학년을 2로 변경하라. 

UPDATE STUDENT
SET Year=2
WHERE Sno=300;

(2) 복수의 레코드 변경

[질의] '컴퓨터'과 과목의 학점(Credit)을 1학점씩 증가시켜라.

UPDATE COURSE
SET Credit=Credit+1
WHERE Dept='컴퓨터';

(3) 부속 질의문을 이용한 변경

[질의] '컴퓨터'과 학생의 기말 성적을 5점씩 가산하라.

UPDATE ENROL
SET Final=Final+5
WHERE Sno IN
	(SELECT Sno
 	   FROM STUDENT	
  	  WHERE Dept='컴퓨터');

[질의] 모든 4학년 학생의 학과를 '데이터베이스' 과목을 개설한 학과로 갱신하라.

UPDATE STUDENT
SET Dept = (SELECT Dept
		FROM COURSE
   		WHERE Cname='데이터베이스')
WHERE Year=4;

6.2.3 데이터의 삽입

기존 테이블에 행을 삽입할 경우에는 다음과 같은 형식의 INSERT문을 사용한다.

INSERT
INTO 테이블[(열_이름_리스트)]
VALUES(열_값_리스트);

또는

INSERT 
INTO 테이블[(열_이름_리스트)]
SELECT 문;

 

(1) 레코드 직접 삽입

[질의] 학번 : 600, 이름 : '박상철', 학년 : 1, 학과 : '컴퓨터'인 학생을 삽입하라.

INSERT
INTO STUDENT(Sno, Sname, Year, Dept)
VALUES(600, '박상철', 1, '컴퓨터');

(2) 부속 질의문을 이용한 레코드 삽입

[질의] 학생 테이블에서 '컴퓨터'과 학생의 학번, 이름, 학년을 검색하여 테이블 컴퓨터(COMPUTER)에 삽입하라.

INSERT
INTO COMPUTER(Sno, Sname, Year)
SELECT Sno, Sname, Year
FROM STUDENT
WHERE Dept='컴퓨터';

6.2.4 데이터의 삭제

SQL 테이블에서의 삭제는 기본적으로 튜플을 대상으로 한다. 기존 테이블의 레코드를 삭제할 때는 다음 형식의 DELETE문을 사용한다.

DELETE
FROM 테이블
[WHERE 조건];

 

(1) 하나의 레코드 삭제

[질의] 학번 100인 학생을 삭제하라.

DELETE
FROM STUDENT
WHERE Sno=100;

(2) 복수의 레코드 삭제

[질의] 등록(ENROL) 테이블의 모든 행을 삭제하라.

DELETE
FROM ENROL;

(3) 부속 질의문을 사용한 삭제

[질의] 과목 'C413'의 기말 성적이 60점 미만인 '컴퓨터'과 학생을 등록 테이블에서 삭제하라.

DELETE
FROM ENROL
WHERE Cno='C413' AND FINAL<60
	AND ENROL.Sno IN (SELECT Sno
    		FROM STUDENT
        	WHERE Dept='컴퓨터');

6.3 SQL 뷰

  • 뷰(view)는 기본적으로 다른 테이블로부터 유도된 이름을 가진 가상 테이블(virtual table)을 말한다.
  • 즉 기본 테이블(base table)은 물리적으로 구현되어 데이터가 실제로 저장되지만 뷰는 반드시 물리적으로 구현되어 있는 것은 아니다.

6.3.1 뷰의 생성

SQL에서 뷰를 생성할 때는 다음과 같은 형식의 CREATE VIEW문을 사용한다.

CREATE VIEW 뷰_이름[(열_이름_리스트)]
	AS SELECT문
    [WITH CHECK OPTION];

AS SELECT문은 일반 검색문과 같은데 다만 UNION이나 ORDER BY를 사용할 수 없다.  예를 들어, STUDENT 테이블의 '컴퓨터'과 학생들로 구서된 컴퓨터과 학생 즉 'CSTUDENT'라는 뷰를 생성한다면 그 정의문은 다음과 같다.

CREATE VIEW CSTUDENT(Sno, Sname, Year)
	AS SELECT Sno, Sname, Year
    		FROM STUDENT
       	 	WHERE Dept='컴퓨터'
        	WITH CHECK OPTION;

다음 CREATE VIEW 정의문은 위의 정의문과 동등하다.

CREATE VIEW CSTUDENT
	AS SELECT Sno, Sname, Year
    		FROM STUDENT
      		 WHERE Dept='컴퓨터'
       		 WITH CHECK OPTION;
  • 뷰는 사실상 학생 기본 테이블을 들여다보는 유리창(window)과 같다. 
  • 뷰는 실행시간에만 구체화되는 특수한 테이블이다. 
  • WITH CHECK OPTION; 절은 이 뷰에 대한 갱신이나 삽입 연산을 실행할 때 뷰 정의 조건(Dept='컴퓨터')을 위반하면 실행이 거부된다는 것을 명세하는 것이다. 

기본 테이블 학생(STUDENT)의 컴퓨터과 학생(CSTUDENT) 뷰

  • 뷰 정의문에서 열 이름이 명세되지 않으면 AS SELECT문에 나오는 열의 이름을 그대로 상속받는다. 
  • 정의하는 뷰의 어떤 열이 집계 함수나 산술식 또는 상수로부터 유도되어 열의 이름을 상속받을 수 없는 경우거나 열 이름을 상속받았을 때 열이 이름이 중복되는 경우에는 뷰의 정의문에 새로운 열의 이름을 반드시 명세하여야 한다.
CREATE VIEW DEPTSIZE(Dept, Size)
	AS SELECT Dept, COUNT(*)
    		FROM STUDENT
      	 	 GROUP BY Dept;
  • 이 DEPTSIZE 뷰 정의문에서 두 번째 열은 집계 함수로부터 유도되기 때문에 열의 이름을 상속받을 수 없어 Size로 명세 하였다.
  • 이 DEPTSIZE 뷰는 또한 기본 테이블의 단순한 행과 열로 된 부분 집합이 아니라 기본 테이블의 통계적 요약 테이블로 볼 수 있다. 이 뷰는 다음과 같이 정의할 수도 있다.
CREATE VIEW DEPTSIZE
	AS SELECT Dept, COUNT(*) AS Size
    		FROM STUDENT
        	GROUP BY Dept;

뷰는 다음과 같이 두 개 이상의 테이블을 조인해서 정의할 수도 있다.

CREATE VIEW HONOR(Sname, Dept, Grade)
	AS SELECT STUDENT.Sname, STUDENT.Dept, ENROL.Final
    		FROM STUDENT, ENROL
        	WHERE STUDENT.Sno=ENROL.Sno
        		AND ENROL.Final>90;

또 일단 정의된 뷰를 이용해서 또 다른 뷰를 정의하는 예는 다음과 같다.

CREATE VIEW COMHONOR
	AS SELECT Sname
    		FROM HONOR
        	WHERE Dept='컴퓨터';

6.3.2 뷰의 제거

뷰의 정의는 기본 테이블처럼 ALTER문을 이용하여 변경할 수 없다. 다만 필요 없는 뷰는 제거하고 필요한 뷰를 정의하면 된다. 뷰를 제거할 때는 다음과 같은 형식의 DROP문을 사용한다.

DROP VIEW 뷰_이름{RESTRICT|CASCADE};

6.3.3 뷰의 조작 연산

  • 뷰는 테이블과 다름없이 검색(SELECT)문을 사용할 수 없다. 그러나 삽입(INSERT)이나 삭제(DELETE), 갱신(UPDATE)문을 뷰에 사용하는 데는 상당한 제한이 있다.
  • 기본적으로 모든 뷰가 삽입, 삭제, 갱신의 대상이 되는 것은 아니다.
  • 예를 들어, 다음과 같이 정의된 두 개의 뷰가 있다고 하자.
CREATE VIEW STUDENT_VIEW1
	AS SELECT Sno, Dept
    		FROM STUDENT;
           
CREATE VIEW STUDENT_VIEW2
	AS SELECT Sname, Dept
    		FROM STUDENT;
  • 이 두 뷰 가운데 STUDENT_VIEW1은 이론적으로 삽입, 삭제, 갱신, 검색이 가능하지만 STUDENT_VIEW2는 이론적으로 그렇지 않다.
  • STUDENT_VIEW1에 레코드를 하나 삽입한다면 이것은 곧 STUDENT 기본 테이블에 삽입하는 것이 된다. 이때 뷰에 나타나지 않은 열의 값은 널(NULL)로 된다. 또 뷰 STUDENT_VIEW1에서 어떤 레코드를 삭제하면 STUDENT 테이블에서 삭제하는 것이 되고 갱신한다면 기본 테이블 STUDENT의 레코드를 갱신하는 결과가 된다.
  • STUDENT_VIEW2에 대해서는 레코드를 삽입할 수 없다. 왜냐하면 STUDENT_VIEW2가 기초로 하고 있는 기본 테이블 STUDENT의 학번(Sno)은 NOT NULL로 명세되어 널(NULL)값을 가질 수 없는데 만일 STUDENT_VIEW2에 대한 레코드 삽입은 학번(Sno)의 값이 널 값으로 되기 때문이다. 
  • 이 뷰 STUDENT_VIEW1과 STUDENT_VIEW2의 중요한 차이는 STUDENT_VIEW1은 하나의 기본 테이블 STUDENT에서 유도된 뷰로서 기본 키를 포함하는 행의 부분 집합으로 구성되었지만 STUDENT_VIEW2는 기본 키를 포함하고 있지 않다는 것이다. 

뷰의 분류

변경이 허용되지 않는 경우

  1. 뷰의 열이 상수나 산술 연산자 또는 함수가 사용된 산술 식으로 만들어지면 변경이 허용되지 않는다.
  2. 집계 함수(COUNT, SUM, AVG, MAX, MIN)가 관련되어 정의된 뷰는 변경할 수 없다
  3. DISTINCT, GROUP BY 또는 HAVING이 사용되어 정의된 뷰는 변경할 수 없다.
  4. 두 개 이상의 테이블이 관련되어 정의된 뷰는 변경할 수 없다.
  5. 변경할 수 없는 뷰를 기초로 정의된 뷰는 저의할 수 없다.

6.3.4 뷰의 장단점

장점

  1. 뷰는 데이터의 논리적 독립성을 어느 정도 제공할 수 있다. 뷰가 정의된 기본 테이블이 확장된다든지 뷰가 속해 있는 데이터베이스에 테이블이 더 늘어난다고 하더라도 기존의 뷰를 사용하는 프로그램이나 사용자는 아무런 영향을 받지 않는다.
  2. 뷰는 데이터의 접근을 제어함으로써 보안을 제공할 수 있다. 뷰를 통해서만 데이터를 접근하게 하면 뷰에 나타나지 않은 데이터를 안전하게 보호하는 효율적인 기법으로 사용할 수 있다. 
  3. 사용자의 데이터 관리를 간단하고 쉽게 해 준다. 필요한 데이터만 뷰로 정의해서 처리할 수 있기 때문에 관리가 용이하고 질의문이 간단해진다.
  4. 여러 사용자의 상이한 응용이나 요구를 지원해 줄 수 있다. 하나의 테이블로 여러 개의 상이한 뷰를 정의하여 사용자의 요구에 따라 활용하게끔 한다.

단점

  1. 뷰는 그 정의를 변경할 수 없다.
  2. 뷰는 삽입, 삭제, 갱신 연산에 많은 제한을 가지고 있는 것 등이다. 

6.4 삽입 SQL

  • 삽입 SQL은 근본적으로 이중 모드(dual-mode) 원리를 가지고 있다. 이것은 터미널에서 대화식으로 사용할 수 있는 SQL문은 모두 응용 프로그램에서도 사용할 수 있다는 것이다.

6.4.1 응용 프로그램의 특징

  1. 응용 프로그램에서 삽입 SQL문은 명령문 앞에 'EXEC SQL'을 붙여 다른 호스트 언어의 명령문과 쉽게 구별할 수 있게 한다. 또한 삽입 SQL문 끝은 세미콜론(;)과 같은 특별한 종료 심벌을 붙여 표현한다.
  2. 삽입 SQL 실행문은 호스트 언어의 실행문이 사용되는 곳이면 어디나 나타낼 수 있다. 대화식 SQL과 달리 삽입 SQL문에는 실행문과 비 실행문이 있는데 DECLARE CURSOR, BEGIN, END, DECLARE SECTION과 같은 SQL문은 비 실행문이다.
  3. 삽입 SQL문은 호스트 변수(host variable) 즉 호스트 프로그램 변수를 포함할 수 있다. SQL문 속에서 이 호스트 변수는 다른 SQL 필드 이름과 구별하기 위해 콜론(:)을 앞에 붙인다. 호스트 변수는 대화식 SQL 조작문에서 상수 대신 사용할 수 있다. 이 호스트 변수는 또한 검색(SELECT, FETCH) 결과를 저장하는 장소를 나타내기 위해서 INTO절에 나타날 수 있다.
  4. SQL 문에서 사용할 호스트 변수는 사용하기 전에 반드시 삽입 SQL 선언인 BEGIN/END DECLARE SELECTION 속에서 선언되어야 한다. 이 삽입 SQL 선언부는 여러 개 있어도 무방하다.
  5. 모든 삽입 SQL 프로그램은 SQLSTATE라는 5문자로 된 스트링 타입의 호스트 변수를 포함한다. SQL문이 실행되면 실행 상태(성공, 실패, 오류) 표시가 이 SQLSTATE 변수를 통해 프로그램에 전달된다. 전달된 SQLSTATE 변수 값이 "00000"이면 SQL문이 성공적으로 실행된 것이고, "02000"이면 실행은 했지만 아무런 데이터도 검색하지 못했다는 것을 의미한다. 이 SQLSTATE 변수를 사용하지 않고 SQLCODE라는 정소 변수를 사용할 수도 있지만 SQLSTATE 변수를 사용하는 것이 더 표준화된 형식이다.
  6. 삽입 SQL문의 호스트 변수의 데이터 타입은 이에 대응하는 데이터베이스 필드의 SQL 데이터 타입과 일치해야 된다. 또 값을 전달받아야 될 필드가 너무 작으면 지정문에서 처음 숫자들이나 문자들이 탈락되고 에러 표시가 프로그램에 전달된다.
  7. 호스트 변수와 데이터베이스 필드의 이름은 같아도 된다. 왜냐하면 호스트 변수는 앞에 콜론을 붙여서 쉽게 구별되기 때문이다. 
  8. 앞에서 언급했듯이 SQL문을 실행하고 나면 SQLSTATE 변수에 반환된 값을 검사해야 된다. 이 과정을 간단히 하기 위해 다음과 같은 WHENEVER문을 사용할 수 있다.
EXEC SQL WHENEVER <조건> <행동>;

응용 프로그램에서의 삽입 SQL


6.4.2 커서가 필요 없는 데이터 조작

(1) 단일 레코드 검색

학번이 호스트 변수  :sno로 주어지는 학생의 이름과 학과를 검색하라.

EXEC SQL SELECT Sname, Dept
	INTO :sname, :dept
   	 FROM STUDENT
   	 WHERE Sno = :sno;

(2) 갱신

과목 'C413'에 등록한 학생의 기말 성적(Final)을 호스트 변수 :new 값만큼 증가시켜라.

EXEC SQL UPDATE ENROL
	SET Final=Final+ :new
    	WHERE Cno ='C413';

(3) 삭제

호스트 변수 :sno의 값을 가진 학생의 모든 등록(ENROL) 레코드를 삭제하라.

EXEC SQL DELETE
	FROM ENROL	
    	WHERE Sno = :sno

(4) 삽입

호스트 변수 :sno, :sname, :dept들로 값이 주어지는 학생 레코드 하나를 학생 테이블에 삽입하라.

EXEC SQL INSERT
	INTO STUDENT(Sno, Sname, Dept)
    	VALUES(:sno, :sname, :dept);

6.4.3 커서를 이용하는 데이터 조작

커서(cursor)

  • SELECT문과 호스트 프로그램 사이를 연결
  • SELECT문으로 검색되는 여러개의 레코드(튜플)를 대상으로 정의됨

활동 세트(active set) : SELECT문으로 검색된 레코드 집합 실행 시에 활동 세트에 있는 레코드 해를 지시 


6.4.4 다이내믹 SQL

  • 다이나믹 SQL(dynamic SQL)은 특별히 일반 대화식 온라인 응용을 실행 시간(runtime)에 구성할 수 있는 삽입 SQL들로 되어 있다.
  • 온라인 응용은 간단히 말해 온라인 터미널로 데이터베이스 접근을 지원하는 응용 프로그램이다.
  • 따라서 이 기능은 온라인 응용 프로그램을 작성해야만 되는 사람들에게 특별히 필요한 것이다. 
  • 통상적인 온라인 응용의 수행 과정은 다음과 같다.
    1. 터미널로부터 명령문을 접수
    2. 입력된 명령문의 분석
    3. 데이터베이스에 대한 적절한 SQL 명령문으로 지시
    4. 터미널로 메시지나 결과를 전송