INSERT — 테이블에 새 행을 추가
[ WITH [ RECURSIVE ]with_query
[, ...] ] INSERT INTOtable_name
[ ASalias
] [ (column_name
[, ...] ) ] [ OVERRIDING { SYSTEM | USER } VALUE ] { DEFAULT VALUES | VALUES ( {expression
| DEFAULT } [, ...] ) [, ...] |query
} [ ON CONFLICT [conflict_target
]conflict_action
] [ RETURNING * |output_expression
[ [ AS ]output_name
] [, ...] ]conflict_target
은 다음 중 하나이다: ( {index_column_name
| (index_expression
) } [ COLLATEcollation
] [opclass
] [, ...] ) [ WHEREindex_predicate
] ON CONSTRAINTconstraint_name
conflict_action
은 다음 중 하나이다: DO NOTHING DO UPDATE SET {column_name
= {expression
| DEFAULT } | (column_name
[, ...] ) = [ ROW ] ( {expression
| DEFAULT } [, ...] ) | (column_name
[, ...] ) = (sub-SELECT
) } [, ...] [ WHEREcondition
]
INSERT
테이블에 새 행을 삽입한다.
value 표현식에 지정된 하나 이상의 행을 삽입하거나, 쿼리 결과로부터 0개 이상의 행을 삽입할 수 있다.
대상 칼럼명은 임의의 순서대로 나열할 수 있다. 칼럼명을 지정하지 않는다면,
기본적으로 테이블의 모든 칼럼을 선언된 순서대로,
또는 VALUES
절이나 query
에서 제공되는 칼럼이 N
개 뿐이라면,
앞에서 부터 N
개의 칼럼명을 사용한다.
VALUES
절이나 query
에서 제공되는 값은 왼쪽부터 오른쪽의 순서대로
명시적 또는 암시적 칼럼 목록과 연결된다.
명시적 또는 암시적 칼럼 목록에 존재하지 않는 칼럼은, 그 기본값이 선언된 경우 기본값으로, 아니면 null로 채워진다.
어떠한 칼럼의 표현식이든 올바른 자료형이 아닐 경우, 자동 형변환을 시도한다.
ON CONFLICT
는 unique 제약이나 exclusion 제약 위배 오류를 해소하기 위한,
대체 액션을 지정하기 위해 사용된다. (아래 ON CONFLICT Clause 참고)
선택적인 RETURNING
절은 causes INSERT
로 하여금,
실제 삽입된 (또는, ON CONFLICT DO UPDATE
절이 사용된 경우, 업데이트 된)
각 행을 기반으로하는 값을 계산하고 반환하게 만든다.
이는 주로, 일련 번호와 같이 기본값으로 제공되는 값들을 알고 싶을 때 유용하다.
게다가, 테이블의 칼럼을 이용한 어떠한 표현식이든 가능하다.
RETURNING
목록의 문법은 SELECT
의 출력 목록과 동일하다.
성공적으로 삽입되거나 업데이트 된 행만 반환된다.
예를 들어, ON CONFLICT DO UPDATE ... WHERE
절의
condition
을 충족시키지 못해서
행이 잠겨졌지만 업데이트가 되지 않았을 경우, 해당 행은 반환되지 않는다.
테이블에 삽입하려면 해당 테이블에 대한 INSERT
권한이 있어야 한다.
또한, ON CONFLICT DO UPDATE
가 존재한다면 UPDATE
권한도 있어야 한다.
칼럼 목록이 지정된 경우, 나열된 칼럼에 대한 INSERT
권한만 있으면 된다.
이와 유사하게, ON CONFLICT DO UPDATE
가 지정된 경우, 업데이트 될 칼럼에 대한
UPDATE
권한만 있으면 된다. 다만, ON CONFLICT DO UPDATE
의 경우,
ON CONFLICT DO UPDATE
표현식이나 condition
에서 값을 읽어야 하는 칼럼에 대한
SELECT
권한 또한 필요하다.
RETURNING
절을 사용하려면 RETURNING
에 언급된 모든 칼럼에 대한
SELECT
권한이 필요하다.
물론, 쿼리로부터 행을 삽입하기 위해 query
절을 사용하는 경우라면,
쿼리 내에서 사용되는 모든 테이블과 칼럼에 대한 SELECT
권한이 필요하다.
이 절에서는 새로운 행을 삽입할 때에만 사용되는 매개 변수를 다룬다.
ON CONFLICT
절에서만 배타적으로 사용되는 매개 변수들은
별도로 설명한다.
with_query
WITH
절은, INSERT
쿼리 내에서 이름으로 참조될 수 있는,
하나 이상의 서브쿼리를 지정할 수 있게 한다.
자세한 내용은 7.8절 와 SELECT를 참고하라.
query
(SELECT
문) 또한
WITH
절을 포함할 수 있다.
이 경우, with_query
의 두 집합 모두
query
내에서 참조될 수 있지만,
두 번째 것은 중첩구조상 더 가까이 있을 경우에만 우선순위를 갖는다.
table_name
존재하는 (선택적으로 schema-qualified 된) 테이블의 이름.
alias
table_name
을 대체하는 이름.
별칭이 제공되면, 테이블의 실제 이름을 완전히 숨기게 된다.
이는 특히 ON CONFLICT DO UPDATE
가 excluded
로
명명된 테이블을 대상으로 할 때,
혹여 그 이름이 삽입하려는 행을 나타내는 특별한 테이블의 이름인 경우 유용하다.
column_name
table_name
으로 명명된 테이블에 있는 칼럼명.
해당 칼럼명은, 필요한 경우 서브필드 명이나 array subscript로 제한될 수 있다.
(복합 필드의 몇몇 필드에만 삽입하면 나머지 필드는 null로 채워진다.)
ON CONFLICT DO UPDATE
로 칼럼을 참조하는 경우,
대상 칼럼을 지정할 때 테이블 명을 포함하면 안된다.
예를 들어, INSERT INTO table_name ... ON CONFLICT DO UPDATE
SET table_name.col = 1
은
유효하지 않다. (이는 UPDATE
의 일반적인 동작에 따른 것이다.)
OVERRIDING SYSTEM VALUE
If this clause is specified, then any values supplied for identity columns will override the default sequence-generated values.
For an identity column defined as GENERATED ALWAYS
,
it is an error to insert an explicit value (other than
DEFAULT
) without specifying either
OVERRIDING SYSTEM VALUE
or OVERRIDING USER
VALUE
. (For an identity column defined as
GENERATED BY DEFAULT
, OVERRIDING SYSTEM
VALUE
is the normal behavior and specifying it does nothing,
but PostgreSQL allows it as an extension.)
OVERRIDING USER VALUE
If this clause is specified, then any values supplied for identity columns are ignored and the default sequence-generated values are applied.
This clause is useful for example when copying values between tables.
Writing INSERT INTO tbl2 OVERRIDING USER VALUE SELECT * FROM
tbl1
will copy from tbl1
all columns that
are not identity columns in tbl2
while values for
the identity columns in tbl2
will be generated by
the sequences associated with tbl2
.
DEFAULT VALUES
각 칼럼 값으로 DEFAULT
라고
명시적으로 지정하는 경우,
모든 칼럼이 그 기본값으로 채워질 것이다.
expression
연관 칼럼에 할당할 수식이나 값.
DEFAULT
연관 칼럼이 자신의 기본값으로 채워질 것이다.
An identity column will be filled with a new value generated by the
associated sequence. For a generated column, specifying this is
permitted but merely specifies the normal behavior of computing the
column from its generation expression.
(An OVERRIDING
clause is not permitted in this
form.)
query
삽입될 행을 제공하는 쿼리 (SELECT
문).
문법에 대한 설명은 SELECT문을 참고하라.
output_expression
각 행이 삽입되거나 업데이트 된 뒤, INSERT
명령에 의해 계산되어 반횐될 표현식.
해당 표현식은 table_name
에 명명된 테이블에 있는
어떠한 칼럼명이라도 사용할 수 있다.
삽입되거나 업데이트 된 모든 칼럼을 반환하려면 *
를 기입하라.
output_name
반환된 칼럼에 사용할 이름.
ON CONFLICT
Clause
선택적 ON CONFLICT
절은 unique 위배나
exclusion 제약 위배 오류를 해소하기 위한 대체 액션을 지정한다.
삽입할 각 개별 행에 대해, 삽입이 진행되거나, 또는 conflict_target
에 지정된
arbiter 제약이나 인덱스가 위배되었을 때, 대체 conflict_action
이
수행된다.
ON CONFLICT DO NOTHING
은 대체 액션으로, 단순히 행이 삽입되는 것을 방지한다.
ON CONFLICT DO UPDATE
는 대체 액션으로, 삽입할 행과 충돌하는 기존 행을 업데이트 한다.
conflict_target
은 unique 인덱스 inference을 수행할 수 있다.
inference을 수행할 때, 이는 하나 이상의 index_column_name
칼럼과
index_expression
표현식, 그리고
index_predicate
로 구성된다.
conflict_target
에서 지정한 칼럼/표현식을, 순서와 관계없이 정확히 포함하는
모든 table_name
unique 인덱스는,
arbiter 인덱스로서 inferred (선택)된다
index_predicate
가 지정되면,
inference을 위한 추후 요구사항으로서, arbiter 인덱스를 충족해야 한다.
이는, 그 외의 모든 조건을 만족하는 인덱스가 존재한다면
non-partial unique 인덱스 (predicate가 없는 unique index)가 inferred 될
(그리고 ON CONFLICT
에서 사용될) 것임을 의미한다.
inference 시도가 실패할 경우, 오류가 발생한다.
ON CONFLICT DO UPDATE
는
원자적 INSERT
또는 UPDATE
결과를 보장한다.
높은 동시성에도 불구하고, 독립적인 오류가 없다면 둘 중 한쪽의 결과가 보장된다.
이는 UPSERT — “UPDATE or INSERT”로도 알려져 있다.
conflict_target
arbiter indexes를 선택함으로써,
어떤 충돌이 ON CONFLICT
에서 대체 액션을 취할지 지정한다.
unique 인덱스 inference을 수행하거나,명시적으로 constraint를 명명한다.
ON CONFLICT DO NOTHING
의 경우,
conflict_target
을 지정하는 것은 선택적이다.
이를 생략할 경우, 모든 사용 가능한 제약조건 (그리고 unique 인덱스)에 대한 충돌이 처리된다.
ON CONFLICT DO UPDATE
의 경우,
conflict_target
이 필수로 제공되어야 한다.
conflict_action
conflict_action
은 대체 ON CONFLICT
액션을 지정한다.
이는, DO NOTHING
이 될 수도 있고,
충돌시 유형에 따라 수행되는 UPDATE
액션의
정확한 세부사항을 지정하는 DO UPDATE
절이 될 수도 있다.
ON CONFLICT DO UPDATE
에 있는 SET
과
WHERE
절은 테이블명 (또는 별칭)을 이용해서 기존 행에 접근하거나,
특별한 excluded
테이블을 이용해서, 삽입을 위한 행에 접근할 수 있다.
관련된 excluded
칼럼을 읽어올 대상 테이블에 있는 모든 칼럼에 대해
SELECT
권한이 필요하다.
Note that the effects of all per-row BEFORE
INSERT
triggers are reflected in
excluded
values, since those effects may
have contributed to the row being excluded from insertion.
index_column_name
table_name
column의 이름.
arbiter 인덱스를 infer 하기 위해 사용된다.
CREATE INDEX
포맷을 따른다.
index_column_name
에 대한 SELECT
권한이 필요하다.
index_expression
index_column_name
과 유사하나,
(단순 칼럼이 아닌) 인덱스 정의 내에 나타나는, table_name
칼럼에 있는
infer 표현식에 사용된다.
CREATE INDEX
포맷을 따른다.
index_expression
에 나타나는 모든 칼럼에 대한
SELECT
권한이 필요하다.
collation
지정되면, 관련된 index_column_name
이나
index_expression
이 inference 도중 일치하는 쌍을 찾을 때에
특정 collation을 사용하도록 지시한다.
collations이 제약 위배가 발생하던 안하던 영향을 받지 않기 때문에, 일반적으로 생략된다.
CREATE INDEX
포맷을 따른다.
opclass
지정되면, 관련된 index_column_name
이나
index_expression
이
inference 도중 일치하는 쌍을 찾기위해 특정 연산자 클래스를 사용하도록 지시한다.
동등 semantics가 자료형의 연산자 클래스를 통틀어서 거의 동일하기 때문에,
또한 정의된 unique 인덱스에 동등성에 대한 적절한 정의가 되어 있다고 충분히 신뢰할 수 있기 때문에
이는 일반적으로 생략된다.
CREATE INDEX
포맷을 따른다.
index_predicate
partial unique 인덱스의 inference를 허용하기 위해 사용된다.
예측을 만족하는 (partial 인덱스일 필요는 없는) 모든 인덱는 inferred 될 수 있다.
CREATE INDEX
포맷을 따른다.
index_predicate
내에 나타나는 모든 칼럼에
대한 SELECT
권한이 필요하다.
constraint_name
제약이나 인덱스를 inferring 하는 대신에, 이름으로 arbiter constraint를 명시적으로 지정한다.
condition
boolean
자료형의 값을 반환하는 표현식
ON CONFLICT DO UPDATE
액션이 취해질 때 모든 행이 잠겨지더라도,
이 표현식으로 true가 반환되는 행만 업데이트 된다.
어떠한 충돌이 업데이트 후보로 식별된 이후,
condition
이 마지막으로 계산된다는 점에 주의하라.
ON CONFLICT DO UPDATE
에서 exclusion 제약이 arbiter로서 지원되지 않는다는 점에 주의하라.
모든 경우에, NOT DEFERRABLE
제약과 unique 인덱스만이 arbiter로서 지원된다.
ON CONFLICT DO UPDATE
절이 들어간 INSERT
는
“deterministic” 문장이다.
이는 해당 명령이, 존재하는 어떠한 단일 행에 대해 두번이상 영향을 줄수 없다는 걸 의미한다.
이러한 상황이 발생하면 cardinality violation error가 발생할 것이다.
삽입하려는 행은 arbiter 인덱스나 제약조건에 의해 제약된 속성의 측면에서,
서로 중복되어서는 안된다.
Note that it is currently not supported for the
ON CONFLICT DO UPDATE
clause of an
INSERT
applied to a partitioned table to update the
partition key of a conflicting row such that it requires the row be moved
to a new partition.
ON CONFLICT ON CONSTRAINT
constraint_name
으로 제약조건을 직접 명명하는 것보다
unique 인덱스 inference 를 사용하는 편이 더 좋다.
Inference 는, 덮어쓰는 방식으로,
예를 들면 교체될 인덱스를 drop하기 전에 CREATE UNIQUE INDEX ... CONCURRENTLY
를 사용하는 식으로,
기반 인덱스가 더 많이 또는 덜 동일한 인덱스로 교체되더라도 문제없이 동작할 것이다.
성공적으로 완료되면, INSERT
명령은 아래 형식의 명령 태그를 반환한다.
INSERToid
count
The count
is the number of
rows inserted or updated. oid
is always 0 (it
used to be the OID assigned to the inserted row if
count
was exactly one and the target table was
declared WITH OIDS
and 0 otherwise, but creating a table
WITH OIDS
is not supported anymore).
INSERT
명령에 RETURNING
절이 포함되어 있다면,
그 결과는, 해당 명령에서 삽입되거나 업데이트 되는 행에 대해 계산된 값이며,
RETURNING
목록에 정의된 칼럼 및 값을 포함하는SELECT
문의 결과와 유사하다.
If the specified table is a partitioned table, each row is routed to the appropriate partition and inserted into it. If the specified table is a partition, an error will occur if one of the input rows violates the partition constraint.
films
테이블에 단일 행을 삽입한다:
INSERT INTO films VALUES ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');
이 예제에서, len
칼럼은 생략되었고, 따라서 기본 값을 갖게 된다:
INSERT INTO films (code, title, did, date_prod, kind) VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');
이 예제는 데이터 칼럼에 값을 지정하지 않고 DEFAULT
절을 사용한다:
INSERT INTO films VALUES ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes'); INSERT INTO films (code, title, did, date_prod, kind) VALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama');
기본 값만으로 구성된 행을 삽입한다:
INSERT INTO films DEFAULT VALUES;
다행 VALUES
문법을 사용하여 다수의 행을 삽입한다:
INSERT INTO films (code, title, did, date_prod, kind) VALUES ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'), ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');
이 예제는, films
과 동일한 칼럼 레이아웃을 갖는 tmp_films
테이블로부터
films
테이블로 몇몇 행을 삽입한다:
INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';
이 예제는 배열 칼럼에 삽입한다:
-- Create an empty 3x3 gameboard for noughts-and-crosses INSERT INTO tictactoe (game, board[1:3][1:3]) VALUES (1, '{{" "," "," "},{" "," "," "},{" "," "," "}}'); -- The subscripts in the above example aren't really needed INSERT INTO tictactoe (game, board) VALUES (2, '{{X," "," "},{" ",O," "},{" ",X," "}}');
단일 행을 distributors
테이블에 삽입하고,
DEFAULT
절에 의해 생성된 일련번호를 반환한다:
INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets') RETURNING did;
Acme Corporation의 계정을 관리하는 salesperson의 sales count를 증가시키고, 로그 테이블에, 업데이트된 행 전체와 현재 시각을 기록한다:
WITH upd AS ( UPDATE employees SET sales_count = sales_count + 1 WHERE id = (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation') RETURNING * ) INSERT INTO employees_log SELECT *, current_timestamp FROM upd;
새distributors를 적절하게 삽입 또는 업데이트 한다.
did
칼럼에 나타나는 값을 제약하는 unique 인덱스가 정의되었다고 가정한다.
삽입에 사용되는 값을 참조하기 위해 특별한 excluded
테이블이 사용되었음에 주의하라:
INSERT INTO distributors (did, dname) VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc') ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;
distributor를 삽입하거나, excluded 행 (행 삽입 트리거가 발생한 전후로 제약 칼럼(들)이 일치하는 행)이
이미 존재할 경우 삽입할 행에 대해 아무 작업도 하지 않는다.
예제에서는 did
칼럼에 나타나는 값을 제약하는 unique 인덱스가 정의되어있다고 가정한다:
INSERT INTO distributors (did, dname) VALUES (7, 'Redline GmbH') ON CONFLICT (did) DO NOTHING;
신규 distributors를 적절하게 삽입 또는 업데이트 한다.
예제에서는, did
칼럼에 나타나는 값을 제약하는
unique 인덱스가 정의되어있다고 가정한다.
실제 업데이트 되는 행을 제한하기 위해 WHERE
절이 사용되었다.
(그렇더라도, 업데이트 되지 않은 기존의 행은 여전히 잠겨있을 것이다):
-- 특정 ZIP code에 기반해서 기존 distributor는 업데이트 하지 않는다. INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution') ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')' WHERE d.zipcode <> '21201'; -- 문장 내에서 제약조건을 직접 명명한다. (DO NOTHING 액션을 사용하기 위해 -- 관련된 인덱스를 사용한다) INSERT INTO distributors (did, dname) VALUES (9, 'Antwerp Design') ON CONFLICT ON CONSTRAINT distributors_pkey DO NOTHING;
가능하다면 신규 distributor를 삽입한다.
그렇지 않은 경우 DO NOTHING
.
예제에서는, is_active
Boolean 칼럼이
true
인 행의 부분집합에 대해
did
칼럼에 나타나는 값을 제약하는
unique 인덱스가 정의되었다고 가정한다:
-- 이 문장은 "WHERE is_active"의 서술부로 -- "did"에 대한 partial unique 인덱스를 infer 할 수 있지만, -- 또한 "did" 제약에 일반적인 unique 제약을 사용할 수도 있다 INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International') ON CONFLICT (did) WHERE is_active DO NOTHING;
INSERT
는
RETURNING
절이 PostgreSQL 확장이며,
INSERT
에 WITH
를 사용할 수 있고,
ON CONFLICT
에 대체 액션을 지정할 수 있다는 점을 제외하면,
SQL 표준을 따른다.
또한, 칼럼 명 목록이 생략될 경우
모든 칼럼이 VALUES
절이나 query
로
채워지진 않는다는 점은, 표준에서 허용되지 않는 점이다.
The SQL standard specifies that OVERRIDING SYSTEM VALUE
can only be specified if an identity column that is generated always
exists. PostgreSQL allows the clause in any case and ignores it if it is
not applicable.
query
의 제약사항은
SELECT에 문서화 되어 있다.