INSERT
INSERT#
구문#
insert ::=#
single_table_insert ::=#
returning_clause ::=, subquery ::=
table_clause ::=#
multi_table_insert ::=#
values_clause ::=#
wait_clause ::=#
전제 조건#
SYS 사용자, 테이블 소유자, INSERT ANY TABLE 시스템 권한을 가진 사용자 및 테이블에 대한 INSERT 객체 권한을 가진 사용자만이 이 구문으로 해당 테이블에 레코드를 삽입할 수 있다.
뷰에 레코드를 INSERT할 때, 사용자는 베이스 테이블에 대해서 위와 동일한 권한을 가져야 한다.
설명#
명시한 테이블 또는 특정 파티션에 새로운 레코드를 삽입하는 구문이다. 만약 해당 테이블에 인덱스가 존재할 경우엔 인덱스 데이터도 변경될 것이다.
user_name#
레코드가 삽입될 테이블의 소유자 이름을 명시한다. 생략하면 Altibase는 그 테이블이 현재 세션에 연결된 사용자의 스키마에 속한 것으로 간주한다.
tbl_name#
레코드가 삽입될 테이블의 이름을 명시한다.
view_name#
레코드가 삽입될 뷰의 이름을 명시한다.
subquery#
레코드를 삽입하려는 뷰를 서브쿼리로 명시한다.
NULL#
일부 칼럼의 값은 명시하고 일부 칼럼의 값은 명시하지 않고 데이터를 삽입할 경우, 값을 주지 않은 칼럼에 기본값이 설정되어 있지 않으면 널이 삽입된다. ( TIMESTAMP 칼럼의 기본값은 INSERT 연산이 수행된 시점의 시스템 시각 값이다. 따라서 TIMESTAMP 칼럼의 입력 값을 명시하지 않을 경우 널이 아닌 시스템 시각 값이 삽입된다. )
VALUES 절에 명시적으로 널을 지정하면 널이 삽입된다.
multi_table_insert 절#
다중 테이블 삽입절은 서브쿼리에서 생성된 결과 집합의 행을 한 개 이상의 테이블에 삽입하기 위해 사용된다. 서브쿼리의 select 리스트에 수식이 있다면, VALUES 절에서 참조할 수 있도록 수식에 별칭(alias)을 반드시 주어야 한다.
DEFAULT#
VALUES 절에 DEFAULT를 명시하면 해당 칼럼에 정의된 기본값이 삽입된다. 전체 칼럼들에 대해 기본값을 삽입하려면 DEFAULT VALUES 절을 사용한다.
TIMESTAMP 칼럼에 DEFAULT를 명시하면 시스템 시각 값이 삽입될 것이다.
INSERT ~ SELECT#
SELECT 질의 결과를 테이블에 삽입하는 구문이다. 삽입할 테이블과 조회하는 테이블이 같아도 된다. 삽입할 칼럼의 개수와 조회하는 칼럼의 개수는 동일해야 하며, 대응하는 칼럼은 서로 호환 가능한 데이터 타입이어야 한다.
returning_clause#
DELETE 구문의 returning_clause를 참고하라.
wait_clause#
레코드를 삽입할 테이블에 동일한 키 값으로 아직 커밋되지 않은 레코드가 존재하는 경우 대기해야 하는데, WAIT 옵션을 이용하면 얼마나 대기할지 설정할 수 있다. 설정할 수 있는 시간 단위는 second(초), millisecond(msec, 1/1000초), microsecond(usec, 1/1000000초)이며 표기하지 않으면 초 단위가 적용된다.
반면, NOWAIT 옵션을 사용하면 대기하지 않으므로, 즉시 삽입 실패 메시지를 확인할 수 있다.
HINTS 옵션#
힌트의 문법과 자세한 설명은 "힌트 구문"과 "힌트 목록"을 참고하기 바란다.
주의 사항#
- INSERT 문으로 데이터를 입력할 때, 다음의 사항들을 유념해야 한다.
- 명시한 칼럼의 개수와 삽입할 값들의 개수는 동일해야 하며 호환 가능한 데이터형 이어야 한다.
- 파티션을 지정할 경우 해당 파티션에 일치하지 않는 값은 입력할 수 없다.
- 기본값이 정의되어 있지 않고 NOT NULL 제약이 없는 칼럼에 입력값을 명시하지 않고 INSERT를 수행할 경우, NULL이 삽입된다.
-
CHECK 제약조건으로 인해 INSERT가 실패할 수 있다.
-
Direct-Path INSERT사용에는 다음과 같은 제약이 있다.
- 대상 테이블은 디스크 테이블이어야 하며, LOB 칼럼 또는 인덱스를 가질 수 없다.
- 이중화 대상 테이블에 대해서 Direct-Path INSERT를 사용할 수 없다.
- 대상 테이블은 트리거나 참조 무결성 제약조건을 가질 수 없다.
- 대상 테이블은 CHECK 제약조건을 가질 수 없다.
예제#
단순 데이터 입력#
<질의> 이름이 Louise Leroux인 고객 정보 입력
INSERT INTO customers
VALUES ( '25'
, 'Leroux'
, 'Louise'
, 'student'
,'025282222'
, 'F'
, '0101'
, 150763
, '#3 825 - 17th Ave SW Calgary Canada');
<질의> Rosalia Jung인 고객의 정보 중 사번, 이름, 성별만 입력
INSERT INTO employees(eno, e_firstname, e_lastname, sex)
VALUES ( 21
, 'Rosalia'
, 'Jung'
, 'F');
<질의> 여러 개의 레코드를 한번에 입력(Multi Row Insert)
INSERT INTO goods
VALUES ('Y111100001', 'YY-300', 'AC0001', 1000, 78000)
, ('Y111100002', 'YY-310', 'DD0001', 100, 98000)
, ('Y111100003', 'YY-H5000', 'AC0002', 780, 35800);
복합 데이터 입력#
<질의> 지연중인 주문에 대한 고객 번호와 주문일을 orders 테이블에서 delayed_processing 테이블로 복사하라.
CREATE TABLE delayed_processing
(
cno CHAR(14),
order_date DATE
);
INSERT INTO delayed_processing
SELECT cno
, order_date
FROM orders
WHERE PROCESSING = 'D';
파티션에 데이터 입력#
CREATE TABLE t1 ( i1 INTEGER, i2 INTEGER )
PARTITION BY RANGE ( i1 )
(
PARTITION p1 VALUES LESS THAN ( 300 ),
PARTITION p2 VALUES LESS THAN ( 400 ),
PARTITION p3 VALUES DEFAULT
) TABLESPACE SYS_TBS_DISK_DATA;
INSERT INTO t1 PARTITION ( p1 ) VALUES ( 123, 456 );
1 row inserted.
Direct-Path INSERT 힌트 사용한 입력#
<질의> T1테이블의 모든 데이터를 Direct-Path INSERT 방식으로 T2테이블에 입력한다.
INSERT /*+ APPEND */ INTO t2 SELECT * FROM t1;
다중 테이블 삽입#
<질의> 한번에 여러 개의 행을 하나의 테이블에 삽입한다.
CREATE TABLE t
(
pid INTEGER,
fname VARCHAR(20),
lname VARCHAR(25)
);
INSERT INTO t
VALUES (1, 'Dan', 'Morgan'), (2, 'Jeremiah', 'Wilton'), (3, 'Helen', 'Lofstrom');
<질의> 서브쿼리의 결과를 여러 테이블에 삽입한다.
CREATE TABLE sal_history
(
eno INTEGER,
join_date DATE,
salary NUMBER(10, 2)
);
CREATE TABLE dno_history
(
eno INTEGER,
dno SMALLINT,
chg_date DATE
);
INSERT ALL INTO sal_history VALUES(emp_id, join_date, salary)
INTO dno_history VALUES(emp_id, dept_id, sysdate)
SELECT eno EMP_ID
, join_date
, salary
, dno DEPT_ID
FROM employees;
Returning 절을 사용한 입력#
<질의> 다음 예제는 입력된 행의 값을 출력 바인드 변수 :v1, :v2로 반환한다.
CREATE TABLE employees
(
eno INTEGER,
ename VARCHAR(20)
);
VAR v1 OUTPUT INTEGER;
VAR v2 OUTPUT VARCHAR(30);
PREPARE INSERT INTO employees VALUES (1, 'jake') RETURN eno, ename INTO :v1, :v2;
1 row inserted.
PRINT var
[ HOST VARIABLE ]
-------------------------------------------------------
NAME TYPE VALUE
-------------------------------------------------------
V1 INTEGER 1
V2 VARCHAR(30) jake
조인 뷰에 데이터 입력#
<질의> employees와 departments 테이블의 조인 뷰를 생성한 후, 레코드를 삽입한다.
CREATE VIEW simple_emp AS
SELECT eno
, e_lastname
, e_firstname
, emp.dno dno
FROM employees emp
, departments dept
WHERE emp.dno = dept.dno;
SELECT * FROM simple_emp;
ENO E_LASTNAME E_FIRSTNAME DNO
-------------------------------------------------------------------------
3 Kobain Ken 1001
16 Chen Wei-Wei 1001
.
.
.
20 Blake William 4002
19 rows selected.
INSERT INTO simple_emp(eno, e_lastname, e_firstname, dno) VALUES(50, 'Kim', 'Yong', 1001);
SELECT * FROM simple_emp;
ENO E_LASTNAME E_FIRSTNAME DNO
-------------------------------------------------------------------------
3 Kobain Ken 1001
16 Chen Wei-Wei 1001
50 Kim Yong 1001
.
.
.
20 Blake William 4002
20 rows selected.