Loading...
MySQL 9.5 Reference Manual 9.5의 15.2.7 INSERT Statement의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
15.2.7.1 INSERT ... SELECT Statement 15.2.7.2 INSERT ... ON DUPLICATE KEY UPDATE Statement 15.2.7.3 INSERT DELAYED Statement
1INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] 2 [INTO] tbl_name 3 [PARTITION (partition_name [, partition_name] ...)] 4 [(col_name [, col_name] ...)] 5 { {VALUES | VALUE} (value_list) [, (value_list)] ... } 6 [AS row_alias[(col_alias [, col_alias] ...)]] 7 [ON DUPLICATE KEY UPDATE assignment_list] 8 9INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] 10 [INTO] tbl_name 11 [PARTITION (partition_name [, partition_name] ...)] 12 SET assignment_list 13 [AS row_alias[(col_alias [, col_alias] ...)]] 14 [ON DUPLICATE KEY UPDATE assignment_list] 15 16INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] 17 [INTO] tbl_name 18 [PARTITION (partition_name [, partition_name] ...)] 19 [(col_name [, col_name] ...)] 20 { SELECT ... 21 | TABLE table_name 22 | VALUES row_constructor_list 23 } 24 [ON DUPLICATE KEY UPDATE assignment_list] 25 26value: 27 {expr | DEFAULT} 28 29value_list: 30 value [, value] ... 31 32row_constructor_list: 33 ROW(value_list)[, ROW(value_list)][, ...] 34 35assignment: 36 col_name = 37 value 38 | [row_alias.]col_name 39 | [tbl_name.]col_name 40 | [row_alias.]col_alias 41 42assignment_list: 43 assignment [, assignment] ...
INSERT는 기존 테이블에 새 행을 삽입합니다. INSERT ... VALUES, INSERT ... VALUES ROW(), 그리고 INSERT ... SET 형태의 스테이트먼트는 명시적으로 지정한 값을 기반으로 행을 삽입합니다. INSERT ... SELECT 형태는 다른 테이블 또는 여러 테이블에서 선택된 행을 삽입합니다. 또한 INSERT ... TABLE을 사용하여 단일 테이블에서 행을 삽입할 수도 있습니다.
ON DUPLICATE KEY UPDATE 절이 있는 INSERT는 삽입하려는 행이 UNIQUE 인덱스 또는 PRIMARY KEY에서 중복 값을 유발하는 경우 기존 행을 업데이트할 수 있도록 해 줍니다. 하나 이상의 선택적인 칼럼 별칭을 가진 행 별칭은 삽입할 행을 참조하기 위해 ON DUPLICATE KEY UPDATE와 함께 사용할 수 있습니다.
INSERT ... SELECT 및 INSERT ... ON DUPLICATE KEY UPDATE에 대한 추가 정보는 Section 15.2.7.1, “INSERT ... SELECT Statement” 및 Section 15.2.7.2, “INSERT ... ON DUPLICATE KEY UPDATE Statement”를 참조하십시오.
MySQL 9.5에서 DELAYED 키워드는 서버에 의해 허용되지만 무시됩니다. 그 이유는 Section 15.2.7.3, “INSERT DELAYED Statement”를 참조하십시오.
테이블에 삽입하려면 해당 테이블에 대한 INSERT 권한이 필요합니다. ON DUPLICATE KEY UPDATE 절이 사용되고 duplicate key로 인해 대신 UPDATE가 수행되는 경우, 스테이트먼트는 업데이트할 칼럼에 대한 UPDATE 권한을 필요로 합니다. 읽기만 하고 수정하지 않는 칼럼에 대해서는 SELECT 권한만 필요합니다(예를 들어, ON DUPLICATE KEY UPDATE 절에서 col_name = expr 할당의 오른쪽에만 참조되는 칼럼인 경우).
파티션된 테이블에 삽입할 때는 어떤 파티션 및 서브파티션이 새 행을 허용할지 제어할 수 있습니다. PARTITION 절은 테이블의 하나 이상의 파티션 또는 서브파티션(또는 그 둘 다)의 이름을 콤마로 구분한 목록을 받습니다. 특정 INSERT 스테이트먼트로 삽입될 행 중 어느 하나라도 나열된 파티션과 일치하지 않으면 해당 INSERT 스테이트먼트는 지정된 파티션 집합과 일치하지 않는 행을 찾았다는 오류와 함께 실패합니다. 자세한 정보와 예시는 Section 26.5, “Partition Selection”을 참조하십시오.
_tbl_name_은 행을 삽입할 테이블입니다. 스테이트먼트가 값을 제공하는 칼럼은 다음과 같이 지정합니다:
테이블 이름 뒤에 콤마로 구분된 칼럼 이름을 괄호로 묶어 나열합니다. 이 경우, VALUES 목록, VALUES ROW() 목록 또는 SELECT 스테이트먼트에 의해 각 이름이 지정된 칼럼에 대한 값이 제공되어야 합니다. INSERT TABLE 형식의 경우, 소스 테이블의 칼럼 개수는 삽입할 칼럼 개수와 일치해야 합니다.
INSERT ... VALUES 또는 INSERT ... SELECT에 대해 칼럼 이름 목록을 지정하지 않으면, 테이블의 모든 칼럼에 대한 값이 VALUES 목록, SELECT 스테이트먼트 또는 TABLE 스테이트먼트에 의해 제공되어야 합니다. 테이블의 칼럼 순서를 모르는 경우, DESCRIBE tbl_name을 사용하여 확인하십시오.
SET 절은 각 칼럼에 할당할 값과 함께 칼럼을 이름으로 명시적으로 지정합니다.
칼럼 값은 여러 가지 방식으로 지정할 수 있습니다:
strict SQL 모드가 활성화된 경우, INSERT 스테이트먼트가 기본값이 없는 모든 칼럼에 대해 명시적 값을 지정하지 않으면 오류가 발생합니다. Section 7.1.11, “Server SQL Modes”를 참조하십시오.
VALUES 목록이 모두 비어 있으면, INSERT는 각 칼럼이 해당 기본값으로 설정된 행을 생성합니다:1INSERT INTO tbl_name () VALUES();
strict 모드가 활성화되어 있지 않으면, MySQL은 명시적으로 정의된 기본값이 없는 칼럼에 대해 묵시적 기본값을 사용합니다. strict 모드가 활성화되어 있으면, 기본값이 없는 칼럼이 하나라도 있으면 오류가 발생합니다.
키워드 DEFAULT를 사용하여 칼럼을 명시적으로 기본값으로 설정할 수 있습니다. 이를 통해 테이블의 소수 칼럼을 제외한 나머지 칼럼에 값을 할당하는 INSERT 스테이트먼트를 쉽게 작성할 수 있습니다. 이는 테이블의 각 칼럼에 대한 값을 포함하지 않는 불완전한 VALUES 목록을 작성하지 않아도 되기 때문입니다. 그렇지 않으면 VALUES 목록의 각 값에 대응하는 칼럼 이름 목록을 제공해야 합니다.
생성 칼럼을 명시적으로 삽입하는 경우, 허용되는 유일한 값은 DEFAULT입니다. 생성 칼럼에 대한 정보는 Section 15.1.24.8, “CREATE TABLE and Generated Columns”을 참조하십시오.
표현식에서는 DEFAULT(col_name)을 사용하여 칼럼 _col_name_의 기본값을 생성할 수 있습니다.
칼럼 값을 제공하는 표현식 _expr_의 데이터 타입이 칼럼 데이터 타입과 일치하지 않으면 타입 변환이 일어날 수 있습니다. 주어진 값의 변환 결과는 칼럼 타입에 따라 서로 다른 삽입 값을 초래할 수 있습니다. 예를 들어 문자열 '1999.0e-2'를 INT, FLOAT, DECIMAL(10,6), YEAR 칼럼에 삽입하면, 각각 1999, 19.9921, 19.992100, 1999이 삽입됩니다. INT 및 YEAR 칼럼에 저장되는 값은 문자열을 숫자로 변환할 때 문자열의 앞부분 중 유효한 정수 또는 연도로 간주될 수 있는 부분만 보기 때문에 1999입니다. FLOAT 및 DECIMAL 칼럼의 경우에는 문자열 전체가 유효한 숫자 값으로 간주됩니다.
표현식 _expr_는 값 목록에서 이전에 설정된 어떠한 칼럼도 참조할 수 있습니다. 예를 들어 다음과 같이 할 수 있습니다. 여기서 col2의 값은 이미 할당된 col1을 참조합니다:
1INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
그러나 다음 예는 legal하지 않습니다. 여기서 col1의 값이 그 이후에 할당되는 col2를 참조하기 때문입니다:
1INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
AUTO_INCREMENT 값을 포함하는 칼럼에 대해서는 예외가 있습니다. AUTO_INCREMENT 값은 다른 값 할당 이후에 생성되기 때문에, 할당에서 AUTO_INCREMENT 칼럼을 참조하는 경우 0을 반환합니다.
VALUES 구문을 사용하는 INSERT 스테이트먼트는 여러 행을 삽입할 수 있습니다. 이를 위해 괄호로 묶인 콤마로 구분된 칼럼 값 목록을 여러 개 포함하고, 목록 사이를 콤마로 구분합니다. 예:
1INSERT INTO tbl_name (a,b,c) 2 VALUES(1,2,3), (4,5,6), (7,8,9);
각 값 목록은 행당 삽입할 값 개수와 정확히 일치해야 합니다. 다음 스테이트먼트는 한 개의 값 목록에 9개의 값이 포함되어 있고, 3개의 값이 있는 값 목록 3개가 아니므로 유효하지 않습니다:
1INSERT INTO tbl_name (a,b,c) VALUES(1,2,3,4,5,6,7,8,9);
VALUE는 이 컨텍스트에서 VALUES의 동의어입니다. 둘 중 어느 것도 값 목록 개수나 목록당 값 개수에 대해 어떠한 의미도 갖지 않습니다. 단일 값 목록이든 여러 목록이든, 또 목록당 값 개수와 관계없이 둘 중 어느 것이든 사용할 수 있습니다.
INSERT 스테이트먼트는 VALUES ROW() 구문을 사용하여 여러 행을 삽입할 수도 있습니다. 이 경우 각 값 목록은 다음과 같이 ROW()(행 생성자) 안에 포함되어야 합니다:
1INSERT INTO tbl_name (a,b,c) 2 VALUES ROW(1,2,3), ROW(4,5,6), ROW(7,8,9);
INSERT에 대한 affected-rows 값은 ROW_COUNT() SQL 함수 또는 mysql_affected_rows() C API 함수를 사용하여 얻을 수 있습니다. Section 14.15, “Information Functions” 및 mysql_affected_rows()를 참조하십시오.
여러 값 목록을 사용하는 INSERT ... VALUES 또는 여러 행을 삽입하는 INSERT ... VALUES ROW(), INSERT ... SELECT 또는 INSERT ... TABLE을 사용하는 경우, 스테이트먼트는 다음 형식의 information string을 반환합니다:
1Records: N1 Duplicates: N2 Warnings: N3
C API를 사용하는 경우 mysql_info() 함수를 호출하여 information string을 얻을 수 있습니다. mysql_info()를 참조하십시오.
Records는 스테이트먼트에 의해 처리된 행 개수를 나타냅니다. (Duplicates가 0이 아닐 수 있으므로, 이것이 실제로 삽입된 행 개수와 반드시 같지는 않습니다.) Duplicates는 테이블에 이미 존재하는 유니크 인덱스 값을 중복하기 때문에 삽입할 수 없었던 행 개수를 나타냅니다. Warnings는 어떤 방식으로든 문제가 있었던 칼럼 값 삽입 시도의 개수를 나타냅니다.
warning은 다음 조건 중 어느 하나에서 발생할 수 있습니다:
NOT NULL로 선언된 칼럼에 NULL을 삽입하는 경우. 여러 행을 삽입하는 INSERT 스테이트먼트 또는 INSERT INTO ... SELECT 스테이트먼트의 경우, 칼럼은 칼럼 데이터 타입에 대한 묵시적 기본값으로 설정됩니다. 이는 숫자 타입의 경우 0, 문자열 타입의 경우 빈 문자열(''), 날짜 및 시간 타입의 경우 “zero” 값입니다. INSERT INTO ... SELECT 스테이트먼트는 서버가 SELECT의 결과 집합이 단일 행을 반환하는지 검사하지 않기 때문에 여러 행 삽입과 동일한 방식으로 처리됩니다. (단일 행 INSERT의 경우 NOT NULL 칼럼에 NULL을 삽입하면 warning이 발생하지 않고 스테이트먼트가 오류와 함께 실패합니다.)
숫자 칼럼을 칼럼 범위를 벗어나는 값으로 설정하는 경우. 값은 범위의 가장 가까운 endpoint로 잘립니다.
'10.34 a'와 같은 값을 숫자 칼럼에 할당하는 경우. 뒤쪽의 비숫자 텍스트는 제거되고, 앞쪽에 남은 숫자 부분이 삽입됩니다. 문자열 값에 앞부분 숫자 부분이 없는 경우, 칼럼은 0으로 설정됩니다.
문자열 칼럼(CHAR, VARCHAR, TEXT, BLOB)에 칼럼 최대 길이를 초과하는 문자열을 삽입하는 경우. 값은 칼럼 최대 길이로 잘립니다.
해당 데이터 타입에 대해 유효하지 않은 값을 날짜 또는 시간 칼럼에 삽입하는 경우. 칼럼은 타입에 맞는 적절한 zero 값으로 설정됩니다.
AUTO_INCREMENT 칼럼 값을 포함하는 INSERT 예시는 Section 5.6.9, “Using AUTO_INCREMENT”를 참조하십시오.
INSERT가 AUTO_INCREMENT 칼럼이 있는 테이블에 행을 삽입하는 경우, LAST_INSERT_ID() SQL 함수 또는 mysql_insert_id() C API 함수를 사용하여 해당 칼럼에 사용된 값을 찾을 수 있습니다.
참고
이 두 함수는 항상 동일하게 동작하지는 않습니다. AUTO_INCREMENT 칼럼과 관련된 INSERT 스테이트먼트의 동작에 대해서는 Section 14.15, “Information Functions” 및 mysql_insert_id()를 참조하십시오.
INSERT 스테이트먼트는 다음 modifier를 지원합니다:
LOW_PRIORITY modifier를 사용하면, 다른 클라이언트가 테이블에서 읽고 있지 않을 때까지 INSERT 실행이 지연됩니다. 이에는 기존 클라이언트가 읽고 있는 동안, 또는 INSERT LOW_PRIORITY 스테이트먼트가 대기하는 동안 읽기를 시작한 다른 클라이언트도 포함됩니다. 따라서 INSERT LOW_PRIORITY 스테이트먼트를 실행하는 클라이언트가 매우 오랫동안 대기할 수 있습니다.LOW_PRIORITY는 MyISAM, MEMORY, MERGE와 같이 테이블 레벨 잠금만 사용하는 스토리지 엔진에만 영향을 줍니다.
참고
LOW_PRIORITY는 일반적으로 MyISAM 테이블에서 사용하지 않아야 합니다. 사용할 경우 동시 삽입이 비활성화되기 때문입니다. Section 10.11.3, “Concurrent Inserts”를 참조하십시오.
HIGH_PRIORITY를 지정하면, 서버가 해당 옵션으로 시작된 경우 --low-priority-updates 옵션의 효과를 무시합니다. 또한 동시 삽입이 사용되지 않도록 합니다. Section 10.11.3, “Concurrent Inserts”를 참조하십시오.HIGH_PRIORITY는 MyISAM, MEMORY, MERGE와 같이 테이블 레벨 잠금만 사용하는 스토리지 엔진에만 영향을 줍니다.
IGNORE modifier를 사용하면, INSERT 스테이트먼트를 실행하는 동안 발생하는 무시 가능한 오류는 무시됩니다. 예를 들어 IGNORE가 없으면 테이블에서 기존의 UNIQUE 인덱스 또는 PRIMARY KEY 값을 중복하는 행은 duplicate-key 오류를 발생시키고 스테이트먼트를 중단시킵니다. IGNORE를 사용하면 해당 행은 버려지고 오류가 발생하지 않습니다. 무시된 오류는 대신 warning을 생성합니다.IGNORE는 주어진 값과 일치하는 파티션이 없는 파티션된 테이블에 insert하는 경우에도 유사한 효과를 가집니다. IGNORE 없이 이러한 INSERT 스테이트먼트는 오류와 함께 중단됩니다. INSERT IGNORE가 사용되면, 일치하지 않는 값을 포함하는 행에 대해서는 insert 작업이 조용히 실패하지만, 일치하는 행은 삽입됩니다. 예시는 Section 26.2.2, “LIST Partitioning”을 참조하십시오.
오류를 유발하는 데이터 변환은 IGNORE가 지정되지 않은 경우 스테이트먼트를 중단시킵니다. IGNORE를 사용하면 유효하지 않은 값이 가장 가까운 값으로 조정되어 삽입되고, warning이 생성되지만 스테이트먼트는 중단되지 않습니다. mysql_info() C API 함수를 사용하여 실제로 테이블에 삽입된 행 개수를 확인할 수 있습니다.
자세한 내용은 The Effect of IGNORE on Statement Execution을 참조하십시오.
기존 행을 덮어쓰려면 INSERT 대신 REPLACE를 사용할 수 있습니다. REPLACE는 유니크 키 값이 기존 행을 중복하는 새 행에 대한 처리에 있어서 INSERT IGNORE의 대응물입니다. 새 행은 버려지는 대신 기존 행을 대체합니다. Section 15.2.12, “REPLACE Statement”를 참조하십시오.
ON DUPLICATE KEY UPDATE를 지정하고 UNIQUE 인덱스 또는 PRIMARY KEY에서 duplicate 값을 유발하는 행이 삽입되는 경우, 기존 행에 대한 UPDATE가 발생합니다. 행이 새 행으로 삽입되면 행당 affected-rows 값은 1이고, 기존 행이 업데이트되면 2이며, 기존 행이 현재 값으로 설정되면 0입니다. mysqld에 연결할 때 mysql_real_connect() C API 함수에 CLIENT_FOUND_ROWS 플래그를 지정하면, 기존 행이 현재 값으로 설정될 때 affected-rows 값은 0이 아니라 1입니다. Section 15.2.7.2, “INSERT ... ON DUPLICATE KEY UPDATE Statement”를 참조하십시오.
INSERT DELAYED는 MySQL 5.6에서 deprecated 되었으며, 향후 제거될 예정입니다. MySQL 9.5에서 DELAYED modifier는 허용되지만 무시됩니다. 대신 DELAYED 없이 INSERT를 사용하십시오. Section 15.2.7.3, “INSERT DELAYED Statement”를 참조하십시오.
15.2.6 IMPORT TABLE Statement
15.2.8 INTERSECT Clause