콘텐츠로 이동

INSERT

INSERT#

구문#

insert ::=#

single_table_insert ::=#

single_table_insert

returning_clause ::=, subquery ::=

table_clause ::=#

table_clause

subquery ::=

multi_table_insert ::=#

multi_table_insert

subquery ::=

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.