CREATE TABLE T_DEPT (DEPTNO NUMBER(2) CONSTRAINT T_DEPT_PK PRIMARY KEY, DNAME VARCHAR2(14) CONSTRAINT T_DEPT_NN NOT NULL CONSTRAINT T_DEPT_UK UNIQUE, LOC VARCHAR2(13) DEFAULT 'SEOUL');CREATE TABLE T_EMP (EMPNO NUMBER(4) CONSTRAINT T_EMP_PK PRIMARY KEY, ENAME VARCHAR2(10), SAL NUMBER(7,2) CONSTRAINT T_EMP_CK CHECK (SAL > 0), DEPTNO NUMBER(2) CONSTRAINT T_EMP_FK REFERENCES T_DEPT (DEPTNO));INSERT INTO T_DEPT (DEPTNO, DNAME) VALUES (10, 'ACCOUNTING');INSERT INTO T_DEPT (DEPTNO, DNAME) VALUES (10, 'SALES');INSERT INTO T_DEPT (DEPTNO, DNAME) VALUES (20, 'ACCOUNTING');INSERT INTO T_DEPT (DEPTNO) VALUES (30);INSERT INTO T_EMP VALUES (1, 'KIM', 0, 10);INSERT INTO T_EMP VALUES (1, 'KIM', 100, 99);INSERT INTO T_EMP VALUES (1, 'KIM', 100, 10);DELETE FROM T_DEPT WHERE DEPTNO = 10;DROP TABLE T_EMP PURGE;DROP TABLE T_DEPT PURGE;
Table created.Table created.1 row created.INSERT INTO T_DEPT (DEPTNO, DNAME) VALUES (10, 'SALES')*ERROR at line 1:ORA-00001: unique constraint (SCOTT.T_DEPT_PK) violated on table SCOTT.T_DEPT columns (DEPTNO)ORA-03301: (ORA-00001 details) row with column values (DEPTNO:10) already existsINSERT INTO T_DEPT (DEPTNO, DNAME) VALUES (20, 'ACCOUNTING')*ERROR at line 1:ORA-00001: unique constraint (SCOTT.T_DEPT_UK) violated on table SCOTT.T_DEPT columns (DNAME)ORA-03301: (ORA-00001 details) row with column values (DNAME:'ACCOUNTING') already existsINSERT INTO T_DEPT (DEPTNO) VALUES (30)*ERROR at line 1:ORA-01400: cannot insert NULL into ("SCOTT"."T_DEPT"."DNAME")INSERT INTO T_EMP VALUES (1, 'KIM', 0, 10)*ERROR at line 1:ORA-02290: check constraint (SCOTT.T_EMP_CK) violatedINSERT INTO T_EMP VALUES (1, 'KIM', 100, 99)*ERROR at line 1:ORA-02291: integrity constraint (SCOTT.T_EMP_FK) violated - parent key not found1 row created.DELETE FROM T_DEPT WHERE DEPTNO = 10*ERROR at line 1:ORA-02292: integrity constraint (SCOTT.T_EMP_FK) violated - child record foundTable dropped.Table dropped.
오류
어긴 제약
상황
ORA-00001
PRIMARY KEY, UNIQUE
같은 값이 이미 있다
ORA-01400
NOT NULL (PK 포함)
NULL 을 넣으려 했다
ORA-02290
CHECK
조건 SAL > 0 이 거짓이다
ORA-02291
FOREIGN KEY
자식에 넣은 값이 부모에 없다 (parent key not found)
ORA-02292
FOREIGN KEY
자식이 참조하는 부모를 지우려 했다 (child record found)
23ai 는 ORA-00001 에 열 이름과 ORA-03301 상세 줄을 덧붙인다. 이전 버전은 ORA-00001: unique constraint (SCOTT.T_DEPT_PK) violated 한 줄이다.
자식 테이블 T_EMP 를 먼저 지웠다. 순서를 바꿔 부모를 먼저 DROP 하면 ORA-02449 가 난다. 부모를 먼저 지우려면 DROP TABLE T_DEPT CASCADE CONSTRAINTS 로 자식의 외래 키를 함께 없앤다.
이름을 주지 않은 제약 조건은 SYS_C008727 같은 시스템 이름을 받는다. 오류 메시지에서 어느 제약인지 알아보기 어렵다.
NULL 과 제약 조건의 관계는 따로 확인했다.
UNIQUE 열에 NULL 을 두 번 넣어도 둘 다 들어갔다. NULL 끼리는 같은 값으로 보지 않는다.
CHECK (A > 0) 열에 NULL 을 넣어도 들어갔다. CHECK 는 조건이 FALSE 일 때만 막고, NULL 비교의 UNKNOWN 은 통과시킨다.
CREATE TABLE 새 테이블 AS SELECT … 는 SELECT 결과의 구조와 행을 그대로 새 테이블로 만든다. WHERE 1 = 2 를 붙이면 구조만 복사한다.
CREATE TABLE T_DEPT (DEPTNO NUMBER(2) CONSTRAINT T_DEPT_PK PRIMARY KEY, DNAME VARCHAR2(14) CONSTRAINT T_DEPT_NN NOT NULL, LOC VARCHAR2(13) DEFAULT 'SEOUL' CONSTRAINT T_DEPT_CK CHECK (LOC <> 'X'));INSERT INTO T_DEPT (DEPTNO, DNAME) VALUES (10, 'ACCOUNTING');CREATE TABLE T_DEPT2 AS SELECT * FROM T_DEPT;SELECT SUBSTR(TABLE_NAME, 1, 8) AS TNAME, CONSTRAINT_TYPE AS T, SUBSTR(SEARCH_CONDITION_VC, 1, 20) AS COND FROM USER_CONSTRAINTS WHERE TABLE_NAME IN ('T_DEPT', 'T_DEPT2') ORDER BY TNAME, T, COND;INSERT INTO T_DEPT2 (DEPTNO, DNAME) VALUES (10, 'SALES');INSERT INTO T_DEPT2 VALUES (20, 'IT', 'X');INSERT INTO T_DEPT2 (DEPTNO) VALUES (30);SELECT * FROM T_DEPT2 ORDER BY DEPTNO, DNAME;DROP TABLE T_DEPT2 PURGE;DROP TABLE T_DEPT PURGE;
Table created.1 row created.Table created.TNAME T COND-------------------------------- - --------------------------------------------------------------------------------T_DEPT C "DNAME" IS NOT NULLT_DEPT C LOC <> 'X'T_DEPT PT_DEPT2 C "DNAME" IS NOT NULL4 rows selected.1 row created.1 row created.INSERT INTO T_DEPT2 (DEPTNO) VALUES (30)*ERROR at line 1:ORA-01400: cannot insert NULL into ("SCOTT"."T_DEPT2"."DNAME") DEPTNO DNAME LOC---------- -------------- ------------- 10 ACCOUNTING SEOUL 10 SALES 20 IT X3 rows selected.Table dropped.Table dropped.
원본 T_DEPT 에는 NOT NULL·CHECK(유형 C)와 PRIMARY KEY(P)가 있다. 복사본 T_DEPT2 에는 NOT NULL 하나만 남았다.
PK 가 없어 DEPTNO 10 이 두 번 들어갔다. CHECK 가 없어 LOC 'X' 도 들어갔다.
10 SALES 의 LOC 가 비었다. DEFAULT 'SEOUL' 도 복사되지 않았다.
NOT NULL 은 그대로라 DNAME 을 뺀 INSERT 는 ORA-01400 이다.
SQL Server 에서는 SELECT … INTO 새 테이블 FROM … 으로 같은 일을 한다.
CREATE TABLE EMP_T AS SELECT EMPNO, ENAME, SAL FROM EMP WHERE DEPTNO = 10;ALTER TABLE EMP_T ADD (BONUS NUMBER(7,2) DEFAULT 0);ALTER TABLE EMP_T ADD (MEMO VARCHAR2(20));ALTER TABLE EMP_T MODIFY (ENAME VARCHAR2(20));ALTER TABLE EMP_T MODIFY (ENAME VARCHAR2(3));ALTER TABLE EMP_T RENAME COLUMN SAL TO SALARY;ALTER TABLE EMP_T DROP COLUMN MEMO;ALTER TABLE EMP_T ADD CONSTRAINT EMP_T_PK PRIMARY KEY (EMPNO);ALTER TABLE EMP_T ADD (GRADE NUMBER NOT NULL);ALTER TABLE EMP_T MODIFY (ENAME NOT NULL);RENAME EMP_T TO T_STAFF;SELECT * FROM T_STAFF ORDER BY EMPNO;TRUNCATE TABLE T_STAFF;SELECT COUNT(*) FROM T_STAFF;DROP TABLE T_STAFF PURGE;
Table created.Table altered.Table altered.Table altered.ALTER TABLE EMP_T MODIFY (ENAME VARCHAR2(3)) *ERROR at line 1:ORA-01441: cannot decrease column length because some value is too bigTable altered.Table altered.Table altered.ALTER TABLE EMP_T ADD (GRADE NUMBER NOT NULL) *ERROR at line 1:ORA-01758: table must be empty to add mandatory (NOT NULL) columnTable altered.Table renamed. EMPNO ENAME SALARY BONUS---------- -------------------- ---------- ---------- 7782 CLARK 2450 0 7839 KING 5000 0 7934 MILLER 1300 03 rows selected.Table truncated. COUNT(*)---------- 01 row selected.Table dropped.
DEFAULT 를 준 열을 ADD 하면 기존 행에도 그 값이 채워진다. BONUS 가 모두 0 이다.
길이를 늘리는 MODIFY 는 언제나 된다. 이미 든 값보다 짧게 줄이면 ORA-01441 이다.
행이 있는 테이블에 DEFAULT 없는 NOT NULL 열은 추가할 수 없다(ORA-01758). 기존 행의 새 열이 NULL 이 되기 때문이다.
PURGE 를 빼면 DROP 한 테이블이 휴지통(Recycle Bin)으로 가서 FLASHBACK TABLE 로 되살릴 수 있다. PURGE 는 휴지통을 거치지 않고 바로 지운다.
SQL Server 는 열 변경에 ALTER TABLE t ALTER COLUMN …, 이름 변경에 sp_rename 을 쓴다.
DCL 은 사용자를 만들고 권한을 다룬다. 실습장 계정에는 권한이 없어 결과표 없이 문법만 본다.
CREATE USER 사용자 IDENTIFIED BY 비밀번호;GRANT 시스템권한 [, …] TO 사용자 [WITH ADMIN OPTION];GRANT 객체권한 [, …] ON 객체 TO 사용자 [WITH GRANT OPTION];REVOKE 권한 [ON 객체] FROM 사용자;
구분
시스템 권한
객체 권한
예
CREATE SESSION, CREATE TABLE, CREATE VIEW
SELECT, INSERT, UPDATE, DELETE ON 테이블
다시 줄 수 있게 하는 옵션
WITH ADMIN OPTION
WITH GRANT OPTION
A → B → C 로 준 뒤 A 가 B 의 권한을 회수하면
B 만 회수, C 는 남는다
C 의 권한도 함께 회수
연쇄 여부는 실습 컨테이너에서 사용자 셋(A·B·C)을 만들어 확인했다.
CREATE USER 만으로는 접속할 수 없다. CREATE SESSION 권한이 있어야 로그인된다.