UPDATE(Transact-SQL)

테이블 또는 뷰의 기존 데이터를 변경합니다.

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

구문

[ WITH <common_table_expression> [...n] ]
UPDATE 
    [ TOP ( expression ) [ PERCENT ] ] 
    { <object> | rowset_function_limited 
     [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
    }
    SET 
        { column_name = { expression | DEFAULT | NULL }
          | { udt_column_name.{ { property_name = expression 
                                | field_name = expression } 
                               | method_name ( argument [ ,...n ] ) 
                              } 
            }
          | column_name { .WRITE ( expression , @Offset , @Length ) }
          | @variable = expression 
          | @variable = column = expression [ ,...n ] 
        } [ ,...n ] 
    [ <OUTPUT Clause> ]
    [ FROM{ <table_source> } [ ,...n ] ] 
    [ WHERE { <search_condition> 
            | { [ CURRENT OF 
                  { { [ GLOBAL ] cursor_name } 
                      | cursor_variable_name 
                  } 
                ]
              }
            } 
    ] 
    [ OPTION ( <query_hint> [ ,...n ] ) ]
[ ; ]

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

인수

  • WITH <common_table_expression>
    UPDATE 문의 범위 내에서 정의된 임시 명명된 결과 집합 또는 뷰를 지정합니다. 이를 CTE(공통 테이블 식)라고 합니다. CTE 결과 집합은 단순 쿼리에서 파생되며 UPDATE 문에서 참조됩니다.

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

  • TOP ( expression**)** [ PERCENT ]
    업데이트할 행의 개수 또는 비율을 지정합니다. expression은 행의 개수 또는 비율이 될 수 있습니다.

    INSERT, UPDATE 또는 DELETE 문에 사용된 TOP 식에서 참조하는 행은 어떠한 순서로도 정렬되지 않습니다.

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

  • server_name
    테이블이나 뷰가 위치한 서버의 이름입니다. 연결된 서버 이름 또는 OPENDATASOURCE 함수를 서버 이름으로 사용합니다. server_name을 지정한 경우에는 database_nameschema_name을 반드시 지정해야 합니다.
  • database_name
    데이터베이스의 이름입니다.
  • schema_name
    테이블이나 뷰가 속한 스키마의 이름입니다.
  • table_or view_name
    행을 업데이트할 테이블 또는 뷰의 이름입니다.

    해당 범위 내의 table 변수 역시 UPDATE 문의 테이블 원본으로 사용할 수 있습니다.

    table_or_view_name에서 참조되는 뷰는 업데이트가 가능해야 하며 해당 뷰의 FROM 절에서 하나의 기본 테이블을 참조해야 합니다. 업데이트할 수 있는 뷰에 대한 자세한 내용은 CREATE VIEW(Transact-SQL)를 참조하십시오.

  • WITH ( <Table_Hint_Limited> )
    대상 테이블에 허용되는 하나 이상의 테이블 힌트를 지정합니다. WITH 키워드와 괄호가 필요합니다. NOLOCK 및 READUNCOMMITTED는 허용되지 않습니다. 테이블 힌트에 대한 자세한 내용은 테이블 힌트(Transact-SQL)를 참조하십시오.
  • SET
    업데이트할 열이나 변수 이름의 목록을 지정합니다.
  • column_name
    변경할 데이터가 포함된 열입니다. column_nametable_or view_name에 있는 열 이름이어야 합니다. ID 열은 업데이트할 수 없습니다.
  • expression
    단일 값을 반환하는 변수, 리터럴 값, 식 또는 괄호로 묶인 하위 SELECT 문입니다. expression이 반환한 값이 column_name 또는 *@variable*의 기존 값을 대체합니다.
  • DEFAULT
    열에 정의한 기본값이 열의 기존 값을 대체하도록 지정합니다. 열에 기본값이 없고 NULL 값을 허용하도록 정의한 경우, 열을 NULL로 변경하는 데 사용할 수도 있습니다.
  • udt_column_name
    사용자 정의 유형의 열입니다.
  • property_name | field_name
    사용자 정의 유형의 공용 속성 또는 공용 데이터 멤버입니다.
  • method_name**(**argument [ ,... n] )
    한 개 이상의 인수를 갖는 udt_column_name의 비정적 공용 변경자(mutator) 메서드입니다.
  • **.**WRITE (expression,*@Offset***,***@Length***)**
    수정할 column_name 값의 섹션을 지정합니다. expressioncolumn_name의 *@Offset*부터 시작하여 *@Length* 단위를 대체합니다. varchar(max), nvarchar(max) 또는 varbinary(max) 열만 이 절을 사용해 지정할 수 있습니다. column_name은 NULL일 수 없으며 테이블 이름이나 테이블 별칭을 붙인 이름일 수 없습니다.

    expressioncolumn_name에 복사되는 값입니다. expressioncolumn_name 형식으로 평가되거나 암시적으로 이러한 데이터 형식으로 변환될 수 있어야 합니다. expression을 NULL로 설정하면 *@Length*가 무시되고 column_name의 값이 *@Offset*에 지정된 값으로 잘립니다.

    *@Offset* 은 expression이 쓰여질 column_name 값의 시작 지점입니다. *@Offset*은 0부터 시작하는 서수 위치이고 bigint이며 음수가 될 수 없습니다. *@Offset*이 NULL이면 업데이트 작업 시 기존 column_name 값 끝에 expression이 추가되고 *@Length*는 무시됩니다. @Offset이 column_name 값의 길이보다 크면 Microsoft SQL Server 2005 데이터베이스 엔진에서 오류를 반환합니다. *@Offset*에 *@Length*를 더한 길이가 기반 열의 값 길이를 초과하면 값의 마지막 문자까지 삭제가 이루어집니다. *@Offset*에 LEN(expression)을 더한 값이 선언된 기반 크기보다 크면 오류가 발생합니다.

    *@Length*는 expression으로 대체될 부분의 길이이며 시작 부분은 *@Offset*으로 지정됩니다. *@Length*는 bigint이며 음수가 될 수 없습니다. *@Length*가 NULL이면 업데이트 작업 시 *@Offset*에서부터 column_name 값의 끝까지 모든 데이터를 제거합니다.

    자세한 내용은 주의를 참조하십시오.

  • **@**variable
    expression에서 반환된 값으로 설정한 선언된 변수입니다.

    SET **@**variable = column = expression은 열과 동일한 값으로 변수를 설정합니다. 이것은 변수를 이미 업데이트한 열 값으로 설정하는 SET **@**variable = column, column = expression과는 다릅니다.

  • <OUTPUT_Clause>
    UPDATE 작업의 일부로서 업데이트된 데이터 또는 이를 바탕으로 한 식을 반환합니다. OUTPUT 절은 원격 테이블 또는 뷰를 대상으로 하는 어떤 DML 문에서도 지원되지 않습니다. 자세한 내용은 OUTPUT 절(Transact-SQL)을 참조하십시오.
  • FROM <table_source>
    업데이트 작업의 기준이 될 테이블, 뷰 또는 파생된 테이블 원본을 지정합니다. 자세한 내용은 FROM(Transact-SQL)을 참조하십시오.

    업데이트되는 개체가 FROM 절의 개체와 같고 개체에 대한 참조가 FROM 절에 하나만 있는 경우, 개체 별칭은 지정될 수도 있고 지정되지 않을 수도 있습니다. 업데이트되는 개체가 FROM 절에서 두 번 이상 나타날 경우 개체에 대한 단 한 번의 참조로 테이블 별칭을 지정할 수는 없습니다. FROM 절의 개체에 대한 다른 모든 참조에는 개체 별칭이 포함되어야 합니다.

    INSTEAD OF UPDATE 트리거가 있는 뷰는 FROM 절이 있는 UPDATE의 대상이 될 수 없습니다.

  • WHERE
    업데이트되는 열을 제한하는 조건을 지정합니다. 어떤 형식의 WHERE 절을 사용하는가에 따라 다음 두 가지 업데이트 형식이 있습니다.

    • 검색 결과 업데이트 - 삭제할 행을 제한하는 검색 조건을 지정합니다.
    • 위치 지정 업데이트 - 커서를 지정하는 CURRENT OF 절을 사용합니다. 이 경우 커서의 현재 위치에서 업데이트 작업이 이루어집니다.
  • <search_condition>
    업데이트할 행을 결정하는 조건을 지정합니다. 조인을 기반으로 하는 조건도 검색 조건으로 사용할 수 있습니다. 검색 조건에 포함할 수 있는 조건자의 개수에는 제한이 없습니다. 조건자와 검색 조건에 대한 자세한 내용은 검색 조건(Transact-SQL)을 참조하십시오.
  • CURRENT OF
    지정한 커서의 현재 위치에서 업데이트가 수행되도록 지정합니다.
  • GLOBAL
    cursor_name이 전역 커서를 참조하도록 지정합니다.
  • cursor_name
    인출이 수행되는 열려진 커서의 이름입니다. 이름이 cursor_name인 전역 커서와 로컬 커서가 모두 있는 경우 이 인수는 GLOBAL이 지정되면 전역 커서를 참조하고 그렇지 않으면 로컬 커서를 참조합니다. 커서는 업데이트를 허용해야 합니다.
  • cursor_variable_name
    커서 변수의 이름입니다. cursor_variable_name은 업데이트를 허용하는 커서를 참조해야 합니다.
  • OPTION ( <query_hint> [ ,... n ] )
    데이터베이스 엔진이 문을 처리하는 방식을 사용자 지정하기 위한 최적화 프로그램 힌트를 지정합니다. 자세한 내용은 쿼리 힌트(Transact-SQL)를 참조하십시오.

주의

UPDATE 문은 로깅되지만 **.**WRITE 절을 사용하는 큰 값 데이터 형식에 대한 부분 업데이트는 최소 로깅됩니다. 자세한 내용은 뒷부분의 "큰 값 데이터 형식 업데이트"를 참조하십시오.

UPDATE 문을 사용자 정의 함수의 본문에서 사용하려면 변경되는 테이블을 table 변수로 지정해야 합니다.

행에 대한 업데이트가 제약 조건이나 규칙을 위반할 경우, 열에 대한 NULL 설정을 위반할 경우 또는 새 값이 호환되지 않는 데이터 형식인 경우에는 문이 취소되고 오류가 반환되며 레코드가 업데이트되지 않습니다.

식을 평가할 때 UPDATE 문에 산술 오류(오버플로, 0으로 나누기 또는 도메인 오류)가 발생하면 업데이트가 실행되지 않으며 나머지 일괄 처리가 실행되지 않고 오류 메시지가 반환됩니다.

클러스터형 인덱스에 참여하는 열을 업데이트하여 클러스터형 인덱스와 행의 크기가 8,060바이트를 넘어서면 업데이트가 실패하고 오류 메시지가 반환됩니다.

UPDATE 문이 클러스터링 키와 한 개 이상의 text, ntext 또는 image 열을 함께 업데이트하는 경우, 이러한 열의 부분 업데이트는 값을 모두 대체하게 됩니다.

모든 charnchar 열은 정의된 길이에 맞도록 오른쪽이 채워집니다.

원격 테이블, 로컬 및 원격 분할 뷰에 대한 UPDATE 문에서는 SET ROWCOUNT 옵션의 설정이 무시됩니다.

ANSI_PADDING이 OFF로 설정되면 varcharnvarchar 열에 삽입되는 데이터에서 후행 공백을 제거합니다(공백만 있는 문자열은 예외). 공백만 있는 문자열은 빈 문자열로 잘립니다. ANSI_PADDING이 ON으로 설정되면 후행 공백이 삽입됩니다. Microsoft SQL Server ODBC 드라이버와 SQL Server용 OLE DB 공급자는 각 연결에 대해 ANSI_PADDING ON을 자동 설정합니다. 이 설정은 ODBC 데이터 원본이나 연결 특성 또는 속성을 통해 구성할 수 있습니다. 자세한 내용은 SET ANSI_PADDING(Transact-SQL)을 참조하십시오.

WHERE CURRENT OF 절을 사용하여 위치 지정 업데이트를 수행하면 커서의 현재 위치에서 단일 행을 업데이트합니다. 이것은 WHERE <search_condition> 절을 사용하여 업데이트될 행을 제한하는 검색 결과 업데이트보다 정확한 방법입니다. 검색 결과 업데이트는 검색 조건이 단일 행을 고유하게 식별하지 못할 경우 여러 행을 변경할 수 있습니다.

FROM 절과 함께 UPDATE 사용

업데이트되는 각 열에 대해 하나의 값만 있도록 지정되지 않은 FROM 절이 문에 포함된 경우(즉, UPDATE 문이 명확히 지정되지 않은 경우) UPDATE 문의 결과가 명확히 정의되지 않습니다. 예를 들어 다음 스크립트의 UPDATE 문에서 Table1에 있는 두 행이 UPDATE 문의 FROM 절 조건을 충족시키지만 Table2.의 행을 업데이트하기 위해 Table1의 어떤 행을 사용할 것인지는 정의되지 않았습니다.

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
    DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
    DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1 
    (ColA int NOT NULL, ColB decimal(10,3) NOT NULL);
GO
CREATE TABLE dbo.Table2 
    (ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES(1, 10.0);
INSERT INTO dbo.Table1 VALUES(1, 20.0);
INSERT INTO dbo.Table2 VALUES(1, 0.0);
GO
UPDATE dbo.Table2 
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
FROM dbo.Table2 
    INNER JOIN dbo.Table1 
    ON (dbo.Table2.ColA = dbo.Table1.ColA);
GO
SELECT ColA, ColB 
FROM dbo.Table2;

FROM 및 WHERE CURRENT OF 절을 함께 사용할 때도 같은 문제가 발생합니다. 다음 예에서 Table2 테이블의 두 행은 UPDATE 문에 있는 FROM 절의 조건을 충족시킵니다. 하지만 Table1의 행을 업데이트하기 위해 Table2의 어떤 행을 사용할 것인지는 정의되지 않았습니다.

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
    DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
    DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1
    (c1 int PRIMARY KEY NOT NULL, c2 int NOT NULL);
GO
CREATE TABLE dbo.Table2
    (d1 int PRIMARY KEY NOT NULL, d2 int NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES (1, 10);
INSERT INTO dbo.Table2 VALUES (1, 20);
INSERT INTO dbo.Table2 VALUES (2, 30);
GO
DECLARE abc CURSOR LOCAL FOR
    SELECT c1, c2 
    FROM dbo.Table1;
OPEN abc;
FETCH abc;
UPDATE dbo.Table1 
SET c2 = c2 + d2 
FROM dbo.Table2 
WHERE CURRENT OF abc;
GO
SELECT c1, c2 FROM dbo.Table1;
GO

사용자 정의 유형 열 업데이트

다음 중 한 가지 방법으로 사용자 정의 유형 열의 값을 업데이트할 수 있습니다.

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

    UPDATE Cities
    SET Location = CONVERT(Point, '12.3:46.2')
    WHERE Name = 'Anchorage';
    
  • **변경자(mutator)**로 표시된 사용자 정의 유형의 메서드를 호출하여 업데이트를 수행합니다. 다음 예에서는 SetXY라는 Point 유형의 변경자 메서드를 호출합니다. 해당 유형의 인스턴스 상태가 업데이트됩니다.

    UPDATE Cities
    SET Location.SetXY(23.5, 23.5)
    WHERE Name = 'Anchorage';
    

    [!참고] Transact-SQL Null 값에서 변경자 메서드를 호출하거나 변경자 메서드에 의해 생성된 새 값이 Null이면 SQL Server에서 오류가 반환됩니다.

  • 등록된 속성 또는 사용자 정의 유형의 공용 데이터 멤버 값을 변경합니다. 값을 제공하는 식은 암시적으로 해당 속성 유형으로 변환할 수 있어야 합니다. 다음 예에서는 사용자 정의 유형 PointX 속성의 값을 변경합니다.

    UPDATE Cities
    SET Location.X = 23.5
    WHERE Name = 'Anchorage';
    

    동일한 사용자 정의 유형 열의 다른 속성을 수정하려면 UPDATE 문을 실행하거나 해당 유형의 변경자(mutator) 메서드를 호출합니다.

큰 값 데이터 형식 업데이트

.WRITE (expression, *@Offset***,***@Length*) 절을 사용하여 varchar(max), nvarchar(max)varbinary(max) 데이터 형식의 부분 또는 전체 업데이트를 수행할 수 있습니다. 예를 들어 varchar(max) 열의 부분 업데이트를 통해 열의 처음 200개 문자만 삭제 또는 변경할 수 있으며, 전체 업데이트를 통해서는 열의 모든 데이터를 삭제 또는 변경할 수 있습니다. **.**WRITE는 데이터베이스 복구 모델이 대량 로그 또는 단순으로 설정되면 새 데이터의 삽입 또는 추가를 최소 로깅하도록 업데이트합니다. 기존 값을 업데이트할 때는 최소 로깅을 사용하지 않습니다. 자세한 내용은 최소 로그 작업을 참조하십시오.

SQL Server 2005 데이터베이스 엔진은 UPDATE 문이 다음 중 한 가지 작업을 유발할 때 부분 업데이트를 전체 업데이트로 변환합니다.

  • 분할된 뷰 또는 테이블의 키 열을 변경합니다.
  • 하나 이상의 행을 변경하고 고유하지 않은 클러스터형 인덱스의 키를 상수가 아닌 값으로 업데이트합니다.

**.**WRITE 절을 사용해 NULL 열을 업데이트하거나 column_name의 값을 NULL로 설정할 수 없습니다.

*@Offset* 및 *@Length*는 varbinaryvarchar 데이터 형식의 경우에는 바이트 단위로, 그리고 nvarchar 데이터 형식의 경우에는 문자 단위로 지정됩니다. 오프셋은 DBCS(더블바이트 문자 집합) 데이터 정렬에 맞게 적절히 계산됩니다.

최상의 성능을 위해 8,040 바이트의 배수인 청크 크기로 데이터를 삽입 또는 업데이트하는 것이 좋습니다.

**.**WRITE 절에 의해 변경된 열을 OUTPUT 절에서 참조하면 **deleted.**column_name의 이전 이미지 또는 **inserted.**column_name의 이후 이미지인 열의 전체 값이 table 변수에 지정된 열로 반환됩니다. 뒷부분의 예 7을 참조하십시오.

다른 문자 또는 binary 데이터 형식에 대해 **.**WRITE의 기능과 동일한 결과를 얻으려면 STUFF(Transact-SQL)를 사용하십시오.

text, ntext 및 image 열 업데이트

열을 NULL로 업데이트하는 경우를 제외하고, UPDATE로 text, ntext 또는 image 열을 변경하면 열이 초기화되고 유효한 텍스트 포인터가 할당됩니다.

text, ntext 또는 image 데이터를 대체 또는 변경하려면 UPDATE 문 대신에 WRITETEXT 또는 UPDATETEXT를 사용하십시오.

ms177523.note(ko-kr,SQL.90).gif중요:
ntext, textimage 데이터 형식은 Microsoft SQL Server 다음 버전에서 제거될 예정입니다. 향후 개발 작업에서는 이 데이터 형식을 사용하지 않도록 하고 현재 이 데이터 형식을 사용하는 응용 프로그램은 수정하십시오. 대신 nvarchar(max), varchar(max)varbinary(max)를 사용합니다. 자세한 내용은 큰 값 데이터 형식 사용을 참조하십시오.

UPDATE 작업에서 INSTEAD OF 트리거 사용

테이블에 대한 UPDATE 작업에 INSTEAD-OF 트리거가 정의되면 UPDATE 문 대신 트리거가 실행됩니다. 이전 버전의 SQL Server에서는 UPDATE 및 기타 데이터 수정 문에서 정의된 AFTER 트리거만 지원되었습니다. INSTEAD OF 트리거가 정의되어 있는 뷰를 직접 또는 간접적으로 참조하는 UPDATE 문에는 FROM 절을 지정할 수 없습니다. INSTEAD OF 트리거에 대한 자세한 내용은 CREATE TRIGGER(Transact-SQL)를 참조하십시오.

변수 및 열 설정

UPDATE 문에서 변수 이름을 사용하면 영향을 받는 이전 값과 새로운 값을 표시할 수 있지만 이는 UPDATE 문이 단일 레코드에 영향을 줄 경우에만 사용할 수 있는 방법입니다. UPDATE 문이 여러 개의 레코드에 영향을 주는 경우 각각의 레코드에 대한 이전 값 및 새로운 값을 반환하려면 OUTPUT 절을 사용하십시오.

사용 권한

대상 테이블에 대한 UPDATE 권한이 필요합니다. 또한 UPDATE 문에 WHERE 절이 포함되거나, SET 절의 expression에서 테이블의 열을 사용할 경우 업데이트하는 중인 테이블에 대해 SELECT 권한이 요구됩니다.

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

1. 단순 UPDATE 문 사용

다음 예에서는 업데이트할 행을 지정하기 위해 WHERE 절을 사용하지 않았을 때 모든 행이 영향을 받는 방식을 보여 줍니다.

이 예에서는 SalesPerson 테이블의 모든 행에 대해 Bonus, CommissionPctSalesQuota 열의 값을 업데이트합니다.

USE AdventureWorks;
GO
UPDATE Sales.SalesPerson
SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL;
GO

UPDATE 문에서 계산된 값을 사용할 수도 있습니다. 다음 예에서는 Product 테이블의 모든 행에 대해 ListPrice 열의 값을 두 배로 만듭니다.

USE AdventureWorks ;
GO
UPDATE Production.Product
SET ListPrice = ListPrice * 2;
GO

2. WHERE 절과 함께 UPDATE 문 사용

다음 예에서는 WHERE 절을 사용해 업데이트할 행을 지정합니다. 예를 들어 Adventure Works Cycles는 자사의 자전거 모델 Road-250을 두 가지 색상(빨간색과 검정색)으로 구분하여 판매합니다. 이 회사는 빨간색 모델의 색상을 금속성 빨간색으로 변경하기로 결정했습니다. 다음 문은 Production.Product 테이블에서 모든 빨간색 Road-250 제품 행을 업데이트합니다.

USE AdventureWorks;
GO
UPDATE Production.Product
SET Color = N'Metallic Red'
WHERE Name LIKE N'Road-250%' AND Color = N'Red';
GO

3. 다른 테이블의 정보와 함께 UPDATE 문 사용

다음 예에서는 SalesPerson 테이블의 SalesYTD 열을 변경하여 SalesOrderHeader 테이블의 가장 최근 판매 기록을 반영합니다.

USE AdventureWorks;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + SubTotal
FROM Sales.SalesPerson AS sp
JOIN Sales.SalesOrderHeader AS so
    ON sp.SalesPersonID = so.SalesPersonID
    AND so.OrderDate = (SELECT MAX(OrderDate)
                        FROM Sales.SalesOrderHeader 
                        WHERE SalesPersonID = 
                              sp.SalesPersonID);
GO

이 예에서는 특정 날짜에 지정된 판매 직원에 대해 하나의 판매 정보만 기록되고 테이블이 최신 상태로 업데이트된 상태라고 가정합니다. 지정된 판매 직원에 대해 두 건 이상의 판매 정보를 같은 날 기록할 수 있는 경우 이 예는 제대로 실행되지 않습니다. 해당 날짜의 실제 판매 실적에 관계없이 이 예는 오류 없이 실행되지만 각 SalesYTD 값은 한 건의 판매 정보로만 업데이트됩니다. 이는 하나의 UPDATE 문이 같은 행을 두 번 업데이트하지 않기 때문입니다.

지정된 판매 직원에 대해 두 번 이상의 판매가 하루에 발생할 수 있는 상황에서, 각 판매 직원에 대한 모든 판매는 다음 예와 같이 UPDATE 문 내에서 함께 집계되어야 합니다.

USE AdventureWorks;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + 
    (SELECT SUM(so.SubTotal) 
     FROM Sales.SalesOrderHeader AS so
     WHERE so.OrderDate = (SELECT MAX(OrderDate)
                           FROM Sales.SalesOrderHeader AS so2
                           WHERE so2.SalesPersonID = 
                                 so.SalesPersonID)
     AND Sales.SalesPerson.SalesPersonID = so.SalesPersonID
     GROUP BY so.SalesPersonID);
GO

4. TOP 절과 함께 UPDATE 사용

다음 예에서는 Employee 테이블의 VacationHours 열에서 임의의 10개 행을 25% 업데이트합니다.

USE AdventureWorks;
GO
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 ;
GO

5. OUTPUT 절과 함께 UPDATE 사용

다음 예에서는 Employee 테이블의 VacationHours 열에서 처음 10개 행을 25% 업데이트합니다. OUTPUT 절은 DELETED.VacationHours 열에서 UPDATE 문을 적용하기 전에 존재했던 VacationHours의 값, 그리고 INSERTED.VacationHours 열에서 업데이트된 값을 @MyTableVartable 변수에 반환합니다.

각각 @MyTableVar의 값과 Employee 테이블의 업데이트 작업 결과를 반환하는 두 개의 SELECT 문이 이어집니다. INSERTED.ModifiedDate 열의 결과는 Employee 테이블의 ModifiedDate 열 값과 다르다는 점에 유의하십시오. 이것은 ModifiedDate의 값을 업데이트하는 AFTER UPDATE 트리거가 Employee 테이블에서 정의되기 때문입니다. 그러나 OUTPUT에서 반환된 열은 트리거가 실행되기 전 데이터를 반영합니다. OUTPUT 절을 사용하는 예를 더 보려면 OUTPUT 절(Transact-SQL)을 참조하십시오.

USE AdventureWorks;
GO
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    OldVacationHours int,
    NewVacationHours int,
    ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 
OUTPUT INSERTED.EmployeeID,
       DELETED.VacationHours,
       INSERTED.VacationHours,
       INSERTED.ModifiedDate
INTO @MyTableVar;
--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO
--Display the result set of the table.
--Note that ModifiedDate reflects the value generated by an
--AFTER UPDATE trigger.
SELECT TOP (10) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

6. WITH common_table_expression 절과 함께 UPDATE 사용

다음 예에서는 ManagerID``12에게 직접 또는 간접적으로 보고하는 모든 직원에 대한 VacationHours 값을 25% 업데이트합니다. 공용 테이블 식은 ManagerID``12에게 직접 보고하는 직원들, 그리고 해당 직원들에게 보고하는 직원들과 같은 식으로 계층 목록을 반환합니다. 공용 테이블 식에 의해 반환된 행만 변경됩니다. 재귀적 공용 테이블 식에 대한 자세한 내용은 공통 테이블 식을 사용하는 재귀 쿼리를 참조하십시오.

USE AdventureWorks;
GO
WITH DirectReports(EmployeeID, NewVacationHours, EmployeeLevel)
AS
(SELECT e.EmployeeID, e.VacationHours, 1
  FROM HumanResources.Employee AS e
  WHERE e.ManagerID = 12
  UNION ALL
  SELECT e.EmployeeID, e.VacationHours, EmployeeLevel + 1
  FROM HumanResources.Employee as e
  JOIN DirectReports AS d ON e.ManagerID = d.EmployeeID
)
UPDATE HumanResources.Employee
SET VacationHours = VacationHours * 1.25
FROM HumanResources.Employee AS e
JOIN DirectReports AS d ON e.EmployeeID = d.EmployeeID;
GO

7. UPDATE를 .WRITE 절과 함께 사용하여 nvarchar(max) 열의 데이터 변경

다음 예에서는 **.**WRITE 절을 사용해 Production.Document 테이블의 nvarchar(max) 열인 DocumentSummary의 부분 값을 업데이트합니다. 대체 단어, 기존 데이터에서 대체할 단어의 시작 위치(오프셋) 및 대체할 문자 수(길이)를 지정하여 componentsfeatures로 대체합니다. 이 예에서는 또한 OUTPUT 절을 사용해 DocumentSummary 열의 이전 및 이후 이미지를 @MyTableVartable 변수에 반환합니다.

USE AdventureWorks;
GO
DECLARE @MyTableVar table (
    DocumentID int NOT NULL,
    SummaryBefore nvarchar(max),
    SummaryAfter nvarchar(max));
UPDATE Production.Document
SET DocumentSummary .WRITE (N'features',28,10)
OUTPUT INSERTED.DocumentID,
       DELETED.DocumentSummary, 
       INSERTED.DocumentSummary 
    INTO @MyTableVar
WHERE DocumentID = 3 ;
SELECT DocumentID, SummaryBefore, SummaryAfter 
FROM @MyTableVar;
GO

8. UPDATE를 .WRITE와 함께 사용하여 nvarchar(max) 열의 데이터 추가 및 제거

다음 예에서는 현재 NULL로 설정된 nvarchar(max) 열에 데이터를 추가하거나 제거합니다. **.**WRITE 절은 NULL 열을 변경하는 데 사용할 수 없기 때문에 열을 먼저 임시 데이터로 채웁니다. 그런 다음 .WRITE 절을 사용하여 이 데이터를 올바른 데이터로 대체합니다. 다음 추가 예에서는 열 값의 끝에 데이터를 추가하고 열에서 데이터를 제거(잘라내기)하고 마지막으로 열에서 일부 데이터를 제거합니다. SELECT 문은 각각의 UPDATE 문에 의한 데이터 변경 내용을 표시합니다.

USE AdventureWorks;
GO
-- Replacing NULL value with temporary data.
UPDATE Production.Document
SET DocumentSummary = N'Replacing NULL value'
WHERE DocumentID = 1;
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO
-- Replacing temporary data with the correct data. Setting @Length to NULL 
-- truncates all existing data from the @Offset position.
UPDATE Production.Document
SET DocumentSummary .WRITE(N'Carefully inspect and maintain the tires and crank arms.',0,NULL)
WHERE DocumentID = 1;
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO
-- Appending additional data to the end of the column by setting 
-- @Offset to NULL.
UPDATE Production.Document
SET DocumentSummary .WRITE (N' Appending data to the end of the column.', NULL, 0)
WHERE DocumentID = 1;
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO
-- Removing all data from @Offset to the end of the existing value by 
-- setting expression to NULL. 
UPDATE Production.Document
SET DocumentSummary .WRITE (NULL, 56, 0)
WHERE DocumentID = 1;
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO
-- Removing partial data beginning at position 9 and ending at 
-- position 21.
UPDATE Production.Document
SET DocumentSummary .WRITE ('',9, 12)
WHERE DocumentID = 1;
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO

9. UPDATE에 OPENROWSET을 사용하여 varbinary(max) 열 변경

다음 예에서는 varbinary(max) 열에 저장된 기존 이미지를 새 이미지로 대체합니다. BULK 옵션을 OPENROWSET 함수에 사용하여 이미지를 열에 로드할 수 있습니다. 이 예에서는 지정된 파일 경로에 Tires.jpg라는 이름의 파일이 존재하는 것으로 가정합니다.

USE AdventureWorks;
GO
UPDATE Production.ProductPhoto
SET ThumbNailPhoto = (
    SELECT *
    FROM OPENROWSET(BULK 'c:\Tires.jpg', SINGLE_BLOB)AS x )
WHERE ProductPhotoID = 1;
GO

참고 항목

참조

CREATE TABLE(Transact-SQL)
CREATE TRIGGER(Transact-SQL)
커서(Transact-SQL)
DELETE(Transact-SQL)
INSERT(Transact-SQL)
OPENROWSET(Transact-SQL)
텍스트 및 이미지 함수(Transact-SQL)
WITH common_table_expression(Transact-SQL)

관련 자료

테이블에서 데이터 업데이트

도움말 및 정보

SQL Server 2005 지원 받기