INSERT(Transact-SQL)

테이블이나 뷰에 한 개 이상의 새 행을 추가합니다. 예를 보려면 INSERT 예(Transact-SQL)를 참조하십시오.

항목 링크 아이콘Transact-SQL 구문 표기 규칙

구문

[ WITH <common_table_expression> [ ,...n ] ]
INSERT 
    [ TOP (expression) [ PERCENT ] ] 
    [ INTO ] 
    { <object> | rowset_function_limited 
      [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
    }
{
    [ (column_list) ] 
    [ <OUTPUT Clause> ]
    { VALUES ( { DEFAULT | NULL | expression } [ ,...n ] ) [ ,...n ] 
    | derived_table 
    | execute_statement
    | <dml_table_source>
    | DEFAULT VALUES 
    } 
} 
[; ]

<object> ::=
{ 
    [ server_name . database_name . schema_name . 
      | database_name .[ schema_name ] . 
      | schema_name . 
    ]
  table_or_view_name
}

<dml_table_source> ::=
    SELECT <select_list>
    FROM ( <dml_statement_with_output_clause> ) 
      [AS] table_alias [ ( column_alias [ ,...n ] ) ]
    [ WHERE <search_condition> ]
    [ OPTION ( <query_hint> [ ,...n ] ) ]

인수

  • WITH <common_table_expression>
    INSERT 문의 범위 내에 정의된 임시로 명명된 결과 집합(공통 테이블 식이라고도 함)을 지정합니다. 결과 집합은 SELECT 문에서 생성됩니다.

    공통 테이블 식은 SELECT, DELETE, UPDATE 및 CREATE VIEW 문에서도 사용할 수 있습니다. 자세한 내용은 WITH common_table_expression(Transact-SQL)을 참조하십시오.

  • TOP (expression) [ PERCENT ]
    삽입할 임의의 행 개수 또는 비율을 지정합니다. expression은 행 개수 또는 비율일 수 있습니다. INSERT, UPDATE 또는 DELETE에 사용된 TOP 식에서 참조된 행은 어떠한 순서로도 정렬되지 않습니다.

    INSERT, UPDATE 및 DELETE 문에서는 괄호를 사용하여 TOP의 expression을 구분해야 합니다. 자세한 내용은 TOP(Transact-SQL)을 참조하십시오.

  • INTO
    INSERT와 대상 테이블 사이에 사용할 수 있는 선택적인 키워드입니다.

  • server_name
    테이블이나 뷰가 위치한 연결된 서버의 이름입니다. server_name은 연결된 서버 이름으로 지정되거나 OPENDATASOURCE 함수로 지정될 수 있습니다.

    server_name을 연결된 서버로 지정할 경우에는 database_name 및 schema_name이 필요합니다. OPENDATASOURCE를 사용하여 server_name을 지정할 경우 database_name 및 schema_name은 일부 데이터 원본에 적용되지 않을 수도 있으며 원격 개체에 액세스하는 OLE DB 공급자 기능에 따라 달라집니다. 자세한 내용은 분산 쿼리를 참조하십시오.

  • database_name
    데이터베이스의 이름입니다.

  • schema_name
    테이블이나 뷰가 속한 스키마의 이름입니다.

  • table_or view_name
    데이터를 받는 테이블 또는 뷰의 이름입니다.

    해당 범위 내에서 table 변수를 INSERT 문의 테이블 원본으로 사용할 수 있습니다.

    table_or_view_name에서 참조되는 뷰는 업데이트가 가능해야 하며 해당 뷰의 FROM 절에서 하나의 기본 테이블을 참조해야 합니다. 예를 들어 여러 테이블 뷰에 대해 INSERT를 수행하려면 반드시 하나의 기본 테이블 열만 참조하는 column_list를 사용해야 합니다. 업데이트할 수 있는 뷰에 대한 자세한 내용은 CREATE VIEW(Transact-SQL)를 참조하십시오.

  • rowset_function_limited
    OPENQUERY 또는 OPENROWSET 함수입니다. 이러한 함수의 사용은 원격 개체에 액세스하는 OLE DB 공급자 기능에 따라 달라집니다. 자세한 내용은 분산 쿼리를 참조하십시오.

  • WITH ( <table_hint_limited> [... n ] )
    대상 테이블에 허용되는 하나 이상의 테이블 힌트를 지정합니다. WITH 키워드와 괄호가 필요합니다.

    READPAST, NOLOCK 및 READUNCOMMITTED는 허용되지 않습니다. 테이블 힌트에 대한 자세한 내용은 테이블 힌트(Transact-SQL)를 참조하십시오.

    중요 정보중요

    INSERT 문의 대상 테이블에 HOLDLOCK, SERIALIZABLE, READCOMMITTED, REPEATABLEREAD 또는 UPDLOCK 힌트를 지정하는 기능은 SQL Server의 이후 버전에서 제거될 예정입니다. 이러한 힌트는 INSERT 문의 성능에 영향을 주지 않습니다. 새로운 개발 작업에서는 이러한 힌트를 사용하지 않도록 하고 현재 이 힌트를 사용하는 응용 프로그램은 수정하십시오.

    INSERT 문의 대상 테이블에 TABLOCK 힌트를 지정하면 TABLOCKX 힌트를 지정하는 것과 동일한 결과를 얻을 수 있습니다. 즉, 테이블이 배타적으로 잠깁니다.

  • (column_list)
    데이터를 삽입할 하나 이상의 열 목록입니다. column_list는 반드시 괄호로 묶고 쉼표로 구분해야 합니다.

    열이 column_list에 없는 경우 데이터베이스 엔진에서는 이 열 정의를 기준으로 하여 값을 제공할 수 있어야 합니다. 그렇지 않은 경우에는 행을 로드할 수 없습니다. 데이터베이스 엔진에서는 다음과 같은 열에 대해 열 값을 자동으로 제공합니다.

    • 열에 IDENTITY 속성이 있는 경우. 다음 증분 ID 값을 사용합니다.

    • 열에 기본값이 있는 경우. 열의 기본값을 사용합니다.

    • timestamp 데이터 형식 열인 경우. 현재 타임스탬프 값을 사용합니다.

    • Null 허용 열인 경우. Null 값을 사용합니다.

    • 계산 열인 경우. 계산된 값을 사용합니다.

    명시적인 값을 ID 열에 삽입할 경우 반드시 column_list와 값 목록을 사용해야 하며 테이블에 대해 SET IDENTITY_INSERT 옵션을 ON으로 설정해야 합니다.

  • OUTPUT Clause
    삽입 작업으로 삽입된 행을 반환합니다. 결과는 처리 중인 응용 프로그램으로 반환되거나 다음 처리를 위해 테이블 또는 테이블 변수에 삽입될 수 있습니다.

    로컬 분할 뷰, 분산형 분할 뷰, 원격 테이블 또는 execute_statement를 포함한 INSERT 문을 참조하는 DML 문에서는 OUTPUT 절이 지원되지 않습니다. <dml_table_source> 절이 포함된 INSERT 문에서는 OUTPUT INTO 절이 지원되지 않습니다.

  • VALUES
    삽입할 데이터 값의 목록을 표시합니다. column_list(지정된 경우) 또는 테이블의 각 열에 대해 반드시 하나의 데이터 값이 있어야 합니다. 값 목록은 괄호로 묶어야 합니다.

    값 목록에 있는 값과 테이블에 있는 열의 순서가 다르거나 테이블의 각 열에 상응하는 값이 목록에 없는 경우에는 반드시 column_list를 사용하여 들어오는 값을 각각 저장하는 열을 명시적으로 지정해야 합니다.

    SQL Server 2008에는 하나의 INSERT 문에 여러 행을 지정하기 위해 Transact-SQL 행 생성자(테이블 값 생성자라고도 함)가 도입되었습니다. 행 생성자는 괄호로 묶고 쉼표로 구분한 여러 값 목록을 포함하는 하나의 VALUES 절로 구성됩니다. 자세한 내용은 테이블 값 생성자(Transact-SQL)를 참조하십시오.

  • DEFAULT
    데이터베이스 엔진이 열에 대해 정의된 기본값을 로드하도록 설정합니다. 열에 대한 기본값이 없고 열에 NULL 값을 사용할 수 있는 경우에는 NULL이 삽입됩니다. timestamp 데이터 형식으로 정의된 열의 경우 다음 타임스탬프 값이 삽입됩니다. ID 열에는 DEFAULT를 사용할 수 없습니다.

  • expression
    상수, 변수 또는 식입니다. 식은 EXECUTE 문을 포함할 수 없습니다.

    nchar, nvarchar 및 ntext 유니코드 문자 데이터 형식을 참조할 때는 'expression' 앞에 대문자 'N'이 접두사로 와야 합니다. 'N'을 지정하지 않으면 SQL Server에서 데이터베이스 또는 열의 기본 데이터 정렬에 해당하는 코드 페이지로 문자열을 변환합니다. 이 코드 페이지에 없는 문자는 모두 손실됩니다. 자세한 내용은 유니코드를 사용한 서버측 프로그래밍을 참조하십시오.

  • derived_table
    테이블에 로드될 데이터의 행을 반환하는 유효한 SELECT 문입니다. SELECT 문은 CTE(공통 테이블 식)를 포함할 수 없습니다.

  • execute_statement
    SELECT 또는 READTEXT 문을 사용하여 데이터를 반환하는 유효한 EXECUTE 문입니다.

    execute_statement 를 INSERT에 사용하는 경우 각 결과 집합은 테이블 또는 column_list 내의 열과 호환되어야 합니다.

    execute_statement는 같은 서버 또는 원격 서버에서 저장 프로시저를 실행하는 데 사용할 수 있습니다. 원격 서버에서 프로시저가 실행된 후 결과 집합이 로컬 서버로 반환되어 로컬 서버의 테이블로 로드됩니다. 연결에 MARS(Multiple Active Result Sets)가 설정된 경우 분산 트랜잭션에서 루프백 연결된 서버에 대해 execute_statement를 실행할 수 없습니다.

    execute_statement가 READTEXT 문을 사용하여 데이터를 반환하는 경우 각 READTEXT 문은 최대 1MB(1024KB)의 데이터를 반환할 수 있습니다. execute_statement는 확장 프로시저에서도 사용할 수 있습니다. execute_statement는 확장 프로시저의 주 스레드에서 반환하는 데이터는 삽입하지만 주 스레드를 제외한 스레드에서 나온 출력은 삽입하지 않습니다.

    테이블 반환 매개 변수는 INSERT EXEC 문의 대상으로는 지정할 수 없지만 INSERT EXEC 문자열이나 저장 프로시저의 원본으로는 지정할 수 있습니다. 자세한 내용은 테이블 반환 매개 변수(데이터베이스 엔진)를 참조하십시오.

  • <dml_table_source>
    INSERT, UPDATE, DELETE 또는 MERGE 문의 OUTPUT 절로 반환되는 행이 대상 테이블에 삽입되고 선택적으로 WHERE 절로 필터링되도록 지정합니다. <dml_table_source>를 지정한 경우 외부 INSERT 문의 대상은 다음과 같은 제한 사항을 따라야 합니다.

    • 뷰가 아닌 기본 테이블이어야 합니다.

    • 원격 테이블일 수 없습니다.

    • 정의된 트리거를 포함할 수 없습니다.

    • 기본 키-외래 키 관계에 참여할 수 없습니다.

    • 트랜잭션 복제에 대한 병합 복제 또는 업데이트할 수 있는 구독에 참여할 수 없습니다.

    데이터베이스의 호환성 수준이 100으로 설정되어야 합니다.

  • <select_list>
    OUTPUT 절에서 반환한 열 중 삽입할 열을 지정하는 쉼표로 구분된 목록입니다. <select_list>의 열은 값을 삽입할 열과 호환되어야 합니다. <select_list>는 집계 함수 또는 TEXTPTR를 참조할 수 없습니다.

    [!참고]

    SELECT 목록에 나열된 모든 변수는 <dml_statement_with_output_clause>의 변경 내용에 관계없이 원본 값을 참조합니다.

  • <dml_statement_with_output_clause>
    OUTPUT 절에 해당 행을 반환하는 유효한 INSERT, UPDATE, DELETE 또는 MERGE 문입니다. 이 문은 WITH 절을 포함할 수 없으며, 원격 테이블 또는 분할 뷰를 대상으로 할 수 없습니다. UPDATE 또는 DELETE가 지정된 경우 커서 기반의 UPDATE 또는 DELETE일 수 없습니다. 원본 행은 중첩된 DML 문으로 참조될 수 없습니다.

  • WHERE <search_condition>
    <dml_statement_with_output_clause>에서 반환된 행을 필터링하는 유효한 <search_condition>을 포함하는 모든 WHERE 절입니다. 자세한 내용은 검색 조건(Transact-SQL)을 참조하십시오. 이 컨텍스트에서 사용할 경우 <search_condition>은 하위 쿼리, 데이터 액세스를 수행하는 스칼라 사용자 정의 함수, 집계 함수, TEXTPTR 또는 전체 텍스트 검색 조건자를 포함할 수 없습니다.

  • DEFAULT VALUES
    새 행이 각 열에 대해 정의된 기본값을 포함하도록 설정합니다.

데이터를 대량 로드하는 최상의 방법

INSERT INTO…SELECT를 사용하여 최소 로깅으로 데이터 대량 로드

INSERT INTO <target_table> SELECT <columns> FROM <source_table>을 사용하여 최소 로깅으로 효율적으로 준비 테이블과 같은 한 테이블의 많은 수의 행을 다른 테이블로 전송할 수 있습니다. 최소 로깅은 문의 효율성을 향상시키며 트랜잭션 작업 중에 사용 가능한 트랜잭션 로그 공간을 꽉 채울 작업의 가능성을 줄여줍니다.

이 문의 최소 로깅을 위해서는 다음과 같은 요구 사항이 충족되어야 합니다.

  • 데이터베이스의 복구 모델이 단순 또는 대량 로그로 설정되어야 합니다.

  • 대상 테이블은 비어 있거나 비어 있지 않은 힙이어야 합니다.

  • 대상 테이블이 복제에 사용되지 않아야 합니다.

  • TABLOCK 힌트가 대상 테이블에 지정되어 있어야 합니다.

MERGE 문의 삽입 작업 결과에 따라 행을 힙에 삽입하는 경우에도 최소 로깅이 가능합니다.

덜 제한적인 대량 업데이트 잠금을 갖는 BULK INSERT 문과 달리 TABLOCK 힌트를 사용하는 INSERT INTO…SELECT는 테이블에 대해 배타적(X) 잠금을 갖습니다. 즉, 병렬 삽입 작업을 사용하여 행을 삽입할 수 없습니다. 잠금에 대한 자세한 내용은 잠금 모드를 참조하십시오.

OPENROWSET 및 BULK를 사용하여 데이터 대량 로드

OPENROWSET 함수는 다음 테이블 힌트를 사용하여 INSERT 문에 대량 로드 최적화를 제공합니다.

  • TABLOCK 힌트를 통해 삽입 작업에 대한 로그 레코드의 수를 최소화할 수 있습니다. 데이터베이스 복구 모델은 단순 또는 대량 로그로 설정되어야 하며 대상 테이블은 복제에 사용될 수 없습니다. 자세한 내용은 대량 가져오기의 최소 로깅을 위한 선행 조건을 참조하십시오.

  • IGNORE_CONSTRAINTS 힌트는 FOREIGN KEY 및 CHECK 제약 조건 검사를 임시로 해제할 수 있습니다.

  • IGNORE_TRIGGERS 힌트는 Trigger 실행을 임시로 해제할 수 있습니다.

  • KEEPDEFAULTS 힌트는 데이터 레코드에 열의 값이 없는 경우 NULL 대신 테이블 열의 기본값(있는 경우)을 삽입하도록 허용합니다.

  • KEEPIDENTITY 힌트는 가져온 데이터 파일의 ID 값이 대상 테이블의 ID 열에 사용되도록 허용합니다.

이러한 최적화는 BULK INSERT 명령에서 사용할 수 있는 최적화와 비슷합니다. 자세한 내용은 테이블 힌트(Transact-SQL)를 참조하십시오.

데이터 형식

행을 삽입할 때는 다음과 같은 데이터 형식 동작을 고려합니다.

  • char, varchar 또는 varbinary 데이터 형식의 열에 값이 로드되는 경우 후행 공백(char 및 varchar의 경우 공백, varbinary의 경우 0)의 채우기 또는 잘라내기는 테이블이 생성될 때 열에 대해 정의된 SET ANSI_PADDING 설정에 의해 결정됩니다. 자세한 내용은 SET ANSI_PADDING(Transact-SQL)을 참조하십시오.

    다음 표에서는 SET ANSI_PADDING이 OFF일 때의 기본 작업을 보여 줍니다.

    데이터 형식

    기본 작업

    char

    정의된 열 너비만큼 공백으로 값을 채웁니다.

    varchar

    공백이 아닌 마지막 문자 또는 단일 공백 문자(공백으로만 이루어진 문자열의 경우)에 대한 후행 공백을 제거합니다.

    varbinary

    후행 0을 제거합니다.

  • 빈 문자열(' ')이 varchar 또는 text 데이터 형식의 열에 로드되는 경우 기본 작업은 길이가 0인 문자열을 로드하는 것입니다.

  • text 또는 image 열에 Null 값을 삽입하면 유효한 텍스트 포인터가 생성되지 않고 8KB 텍스트 페이지도 사전 할당되지 않습니다. text 및 image 데이터 삽입에 대한 자세한 내용은 text, ntext 및 image 함수 사용을 참조하십시오.

  • uniqueidentifier 데이터 형식으로 만든 열은 특수한 형식의 16바이트 이진 값을 저장합니다. ID 열의 경우와 달리 uniqueidentifier 데이터 형식의 열에 대해서는 데이터베이스 엔진이 자동으로 값을 생성하지 않습니다. 삽입 작업 중에는 uniqueidentifier 열에 uniqueidentifier 데이터 형식의 변수 및 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx(하이픈을 포함하여 36자, x는 0-9 또는 a-f 범위의 16진수 값) 형식의 문자열 상수를 사용할 수 있습니다. 예를 들어 6F9619FF-8B86-D011-B42D-00C04FC964FF는 uniqueidentifier 변수 또는 열에 대해 유효한 값입니다. GUID(Globally Unique Identifier)를 가져오려면 NEWID() 함수를 사용하십시오.

사용자 정의 형식 열에 값 삽입

다음과 같은 방법으로 사용자 정의 형식 열에 값을 삽입할 수 있습니다.

  • 사용자 정의 형식의 값을 제공합니다.

  • 사용자 정의 형식에서 SQL Server 시스템 데이터 형식의 암시적 또는 명시적 변환이 지원되는 경우 해당 형식의 값을 제공합니다. 다음 예에서는 문자열의 명시적 변환을 통해 Point 사용자 정의 형식 열에 값을 삽입하는 방법을 보여 줍니다.

    INSERT INTO Cities (Location)
    VALUES ( CONVERT(Point, '12.3:46.2') );
    

    모든 사용자 정의 형식은 이진 형식에서의 암시적 변환이 가능하기 때문에 명시적 변환을 수행하지 않고도 이진 값을 제공할 수 있습니다. 변환 및 사용자 정의 형식에 대한 자세한 내용은 사용자 정의 형식 작업 수행을 참조하십시오.

  • 사용자 정의 형식의 값을 반환하는 사용자 정의 함수를 호출합니다. 다음 예에서는 CreateNewPoint() 사용자 정의 함수를 사용하여 Point 사용자 정의 형식의 새 값을 만들고 이 값을 Cities 테이블에 삽입합니다.

    INSERT INTO Cities (Location)
    VALUES ( dbo.CreateNewPoint(x, y) );
    

오류 처리

TRY…CATCH 구문에 문을 지정하여 INSERT 문에 대한 오류 처리를 구현할 수 있습니다. 자세한 내용은 Transact-SQL에서 TRY...CATCH 사용을 참조하십시오.

INSERT 문이 제약 조건 또는 규칙을 위반하거나 열의 데이터 형식과 호환되지 않는 값을 가진 경우에는 문이 실패하고 오류 메시지가 반환됩니다.

INSERT가 SELECT 또는 EXECUTE를 사용하여 여러 행을 로드하는 경우 로드되는 값 중에서 규칙 또는 제약 조건 위반이 발생하면 문이 중지되며 어떠한 행도 로드되지 않습니다.

식 평가 중 INSERT 문에서 산술 오류(오버플로, 0으로 나누기, 도메인 오류 등)가 발생하면 데이터베이스 엔진은 SET ARITHABORT가 ON으로 설정된 것으로 가정하고 이러한 오류를 처리합니다. 일괄 처리가 중지되고 오류 메시지가 반환됩니다. SET ARITHABORT 및 SET ANSI_WARNINGS가 OFF일 때 INSERT, DELETE 또는 UPDATE 문에서 식 평가 중 산술 오류(오버플로, 0으로 나누기 또는 도메인 오류)가 발생하면 SQL Server는 NULL 값을 삽입하거나 업데이트합니다. 대상 열이 Null 허용이 아니면 삽입이나 업데이트 동작이 실패하고 사용자에게 오류 메시지가 보내집니다. 자세한 내용은 ARITHABORT 및 ARITHIGNORE가 ON으로 설정된 경우의 동작을 참조하십시오.

상호 운용성

테이블이나 뷰에 대한 INSERT 동작에 INSTEAD OF 트리거가 정의되면 INSERT 문 대신 트리거가 실행됩니다. INSTEAD OF 트리거에 대한 자세한 내용은 CREATE TRIGGER(Transact-SQL)를 참조하십시오.

제한 사항

원격 테이블로 값을 삽입할 때 일부 열의 값이 지정되지 않은 경우 사용자가 지정된 값을 삽입할 열을 식별해야 합니다.

SET ROWCOUNT 옵션 설정은 로컬 및 원격 분할 뷰에 대한 INSERT 문에서는 무시됩니다. 또한 이 옵션은 원격 테이블에 대해 실행된 INSERT 문에서는 지원되지 않습니다.

중요 정보중요

SQL Server의 다음 버전에서는 DELETE, INSERT 및 UPDATE 문이 SET ROWCOUNT 사용에 영향을 받지 않게 됩니다. 새 개발 작업에서는 DELETE, INSERT 및 UPDATE 문에 SET ROWCOUNT 옵션을 사용하지 않도록 하고 현재 이 옵션을 사용하는 응용 프로그램은 수정하십시오. 대신 TOP 절을 사용하는 것이 좋습니다.

로깅 동작

INSERT INTO <target_table> SELECT <columns> FROM <source_table>을 사용하거나 BULK 키워드와 함께 OPENROWSET 함수를 사용하는 경우를 제외하고 INSERT 문은 항상 전체 기록됩니다. 이러한 작업은 최소한으로 로깅할 수 있습니다. 자세한 내용은 이 항목의 앞부분에 나오는 "데이터를 대량 로드하는 최상의 방법" 섹션을 참조하십시오.

보안

연결된 서버를 연결하는 동안 보내는 서버에서는 연결된 서버를 대신해서 로그인 이름과 암호를 제공하여 받는 서버에 연결합니다. 이 연결을 사용하려면 sp_addlinkedsrvlogin을 사용하여 연결된 서버 간의 로그인 매핑을 만들어야 합니다. 자세한 내용은 연결된 서버의 보안을 참조하십시오.

OPENROWSET(BULK…)을 사용할 때는 SQL Server에서 가장을 처리하는 방법을 이해하는 것이 중요합니다. 자세한 내용은 BULK INSERT 또는 OPENROWSET(BULK...)를 사용하여 데이터 대량 가져오기의 “보안 고려 사항”을 참조하십시오.

사용 권한

대상 테이블에 대해 INSERT 권한이 필요합니다.

INSERT 권한은 sysadmin 고정 서버 역할, db_owner 및 db_datawriter 고정 데이터베이스 역할 및 테이블 소유자의 멤버에게 기본적으로 부여됩니다. sysadmin, db_owner 및 db_securityadmin 역할의 멤버와 테이블 소유자는 다른 사용자에게 권한을 위임할 수 있습니다.

OPENROWSET 함수에 BULK 옵션을 사용하여 INSERT를 실행하려면 sysadmin 고정 서버 역할 또는 bulkadmin 고정 서버 역할의 멤버여야 합니다.

예를 보려면 INSERT 예(Transact-SQL)를 참조하십시오.