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_name および schema_name も指定する必要があります。
  • database_name
    データベースの名前です。
  • schema_name
    テーブルまたはビューが属するスキーマの名前です。
  • table_or view_name
    行を更新するテーブルまたはビューの名前です。

    table 変数は、そのスコープの中の UPDATE ステートメントでテーブル ソースとして使用できます。

    table_or_view_name によって参照されるビューは更新可能であることが必要です。また、そのビューの FROM 句ではベース テーブルを 1 つだけ参照している必要があります。更新可能なビューの詳細については、「CREATE VIEW (Transact-SQL)」を参照してください。

  • WITH ( <Table_Hint_Limited> )
    対象のテーブルに設定可能なテーブル ヒントを 1 つ以上指定します。キーワード WITH とかっこは必須です。NOLOCK と READUNCOMMITTED は使用できません。テーブル ヒントの詳細については、「テーブル ヒント (Transact-SQL)」を参照してください。
  • SET
    更新する列名または変数名の一覧を指定します。
  • column_name
    変更するデータを含む列です。column_name は、table_or view_name 内に存在している必要があります。ID 列は更新できません。
  • expression
    変数、リテラル値、式、または 1 つの値を返すかっこで囲んだサブセレクト ステートメントです。expression で返される値は、column_name または @variable の既存の値を置き換えます。
  • DEFAULT
    列に格納された値を列に定義された既定値で置き換えることを指定します。列に既定値が定義されておらず、NULL 値が許されている場合は、この句を使用して列を NULL に変更できます。
  • udt_column_name
    ユーザー定義型の列です。
  • property_name | field_name
    ユーザー定義型のパブリック プロパティまたはパブリック データ メンバです。
  • method_name**(**argument [ ,... n] )
    1 つ以上の引数を使用する udt_column_name の静的でないパブリック ミューテータ メソッドです。
  • .WRITE (expression,@Offset,@Length**)**
    column_name の値のセクションを変更することを指定します。expression は、column_name@Offset から始まる @Length 単位を置き換えます。この句では、varchar(max)nvarchar(max)、または varbinary(max) の列だけを指定できます。column_name では NULL 値は許容されません。また、テーブル名やテーブル別名で修飾することもできません。

    expression は、column_name にコピーされる値です。expression は、column_name 型に評価されるか、この型に暗黙的にキャストできる必要があります。expression に NULL が設定されている場合、@Length は無視され、column_name 内の値は指定された @Offset で切り捨てられます。

    @Offset は、expression が書き込まれる、column_name 内の開始位置です。@Offset は、0 から始まる序数の位置であり、データ型は bigint で、負の数は指定できません。@Offset が NULL の場合、更新操作により expression は既存の column_name 値の最後に追加され、@Length は無視されます。@Offset が column_name 値の長さより大きい場合には、Microsoft SQL Server 2005 データベース エンジンによってエラーが返されます。@Offset@Length の和が列の基になる値の終点を超える場合、値の最後の文字までが削除されます。@Offset と LEN(expression) の和が宣言された基になるサイズを超える場合、エラーが発生します。

    @Length は、列内のセクションの長さです。このセクションは、@Offset から始まり、 expression で置き換えられます。@Lengthbigint 型であり、負の数は指定できません。@Length が NULL の場合、更新操作により column_name の値の @Offset から最後までのすべてのデータが削除されます。

    詳細については、「解説」を参照してください。

  • **@**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 句にそのオブジェクトへの参照が 1 つしかない場合、オブジェクトの別名は指定しても指定しなくてもかまいません。更新対象のオブジェクトが FROM 句に 2 つ以上含まれている場合、そのオブジェクトへの単独の参照でテーブルの別名を指定してはなりません。FROM 句にあるオブジェクトへの他のすべての参照に、オブジェクトの別名を含める必要があります。

    INSTEAD OF UPDATE トリガを伴うビューは、FROM 句を伴う UPDATE の対象にはなりません。

  • WHERE
    更新する行を制限する条件を指定します。WHERE 句で使用される形式に基づいて、更新には 2 種類の形式があります。

    • 検索更新では、削除する行を識別する検索条件を指定します。
    • 位置指定更新では、CURRENT OF 句を使用してカーソルを指定します。更新操作は、カーソルの現在位置で行われます。
  • <search_condition>
    更新の対象となる行の条件を指定します。検索条件を結合の基準条件にすることもできます。検索条件に含まれる述語の数に制限はありません。述語および検索条件の詳細については、「検索条件 (Transact-SQL)」を参照してください。
  • CURRENT OF
    指定したカーソルの現在位置で更新を行うことを指定します。
  • GLOBAL
    cursor_name でグローバル カーソルを参照することを指定します。
  • cursor_name
    フェッチを行う、オープンされたカーソルの名前です。cursor_name という名前のグローバル カーソルとローカル カーソルの両方がある場合、GLOBAL を指定すると、この引数はグローバル カーソルを参照します。GLOBAL を指定しないと、この引数はローカル カーソルを参照します。カーソルは、更新可能である必要があります。
  • cursor_variable_name
    カーソル変数の名前です。cursor_variable_name は、更新可能なカーソルを参照している必要があります。
  • OPTION ( <query_hint> [ ,... n ] )
    オプティマイザ ヒントを使用して、データベース エンジンがステートメントを処理する方法をカスタマイズすることを指定します。詳細については、「クエリ ヒント (Transact-SQL)」を参照してください。

解説

UPDATE ステートメントはログに記録されますが、**.**WRITE 句を使用して値の大きなデータ型の一部を更新する場合には、最低限の内容だけがログに記録されます。詳細については、以下の「大きな値のデータ型を更新する」を参照してください。

UPDATE ステートメントをユーザー定義関数の本文で使用できるのは、変更対象のテーブルが table 変数の場合だけです。

行の更新が制約やルールに違反する場合や、列の NULL 値の設定に違反する場合、または新しい値が互換性のないデータ型の場合には、ステートメントは取り消され、エラーが返されます。レコードは更新されません。

式の評価時に UPDATE ステートメントが算術エラー (オーバーフロー、0 による除算、ドメイン エラー) を検出した場合、更新は行われません。バッチの残りの部分は実行されず、エラー メッセージが返されます。

クラスタ化インデックスに関係する列を更新した結果、クラスタ化インデックスと行のサイズが 8,060 バイトを超える場合、更新は失敗し、エラー メッセージが返されます。

UPDATE ステートメントで、クラスタ化キーと 1 つ以上の textntext、または image 列の両方の更新中に、複数の行を変更する場合は、これらの列に対する部分更新は、値の完全な置き換えとして実行されます。

char 列と nchar 列は、すべて定義された長さになるまで右側に空白が埋め込まれます。

リモート テーブル、およびローカルおよびリモート パーティション ビューに対する UPDATE ステートメントの場合、SET ROWCOUNT オプションの設定は無視されます。

ANSI_PADDING を OFF に設定した場合、スペースだけの文字列を除いて、varchar 列および nvarchar 列に挿入したデータからは後続のスペースがすべて削除されます。スペースだけで構成される文字列は空の文字列に切り捨てられます。ANSI_PADDING を ON に設定すると、後続にスペースが挿入されます。Microsoft SQL Server ODBC ドライバおよび OLE DB Provider for SQL Server は、接続するたびに自動的に SET ANSI_PADDING を ON にします。これは、ODBC データ ソースで構成するか、または接続属性やプロパティで設定することができます。詳細については、「SET ANSI_PADDING (Transact-SQL)」を参照してください。

WHERE CURRENT OF 句を使用する位置指定更新では、カーソルの現在位置にある 1 行を更新します。位置指定更新は、WHERE <search_condition> 句を使用して更新する行を識別する検索更新よりも正確です。検索更新は、検索条件が特定の行を識別しない場合に複数の行を変更します。

UPDATE を FROM 句と共に使用する

UPDATE ステートメントの FROM 句を指定する方法が、更新対象の各列に対して使用できる値を 1 つに限定していない場合 (UPDATE ステートメントが非決定的の場合)、UPDATE ステートメントの結果は未定義となります。たとえば、次のスクリプトの UPDATE ステートメントでは、Table1 のどちらの行も 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 
    (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 句の条件を満たします。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
    (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 としてマークされたメソッドを呼び出して更新を行います。次の例では、Point 型の SetXY というミューテータ メソッドを呼び出します。これにより、その型のインスタンスの状態が更新されます。

    UPDATE Cities
    SET Location.SetXY(23.5, 23.5)
    WHERE Name = 'Anchorage';
    
    ms177523.note(ja-jp,SQL.90).gifメモ :
    ミューテータ メソッドを Transact-SQL の NULL 値で呼び出した場合や、ミューテータ メソッドにより生成された新しい値が NULL である場合、エラーが返されます。
  • ユーザー定義型の登録済みプロパティまたはパブリック データ メンバの値を変更します。値を指定する式は、プロパティの型に暗黙的に変換できる必要があります。次の例では、ユーザー定義型 Point のプロパティ X の値を変更します。

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

    同一のユーザー定義型の列のプロパティを複数変更するには、複数の UPDATE ステートメントを実行するか、その型のミューテータ メソッドを呼び出します。

大きな値のデータ型を更新する

varchar(max)nvarchar(max)、および varbinary(max) の各データ型を部分的または完全に更新するには、.WRITE (expression, @Offset**,@Length) 句を使用します。たとえば、varchar(max) 列の部分的な更新では、列の最初の 200 文字だけを削除または変更しますが、完全な更新では、列のすべてのデータを削除または変更します。データベースの復旧モデルに一括ログ復旧モデルまたは単純復旧モデルが設定されている場合、.**WRITE で新しいデータを挿入または追加する際には、最小限しかログに記録されません。既存の値を更新するときには、最小限のログ記録は使用されません。詳細については、「最小ログ記録操作」を参照してください。

SQL Server 2005 データベース エンジンでは、UPDATE ステートメントによって次のどちらかのアクションが行われる場合には、部分的な更新が完全な更新に変換されます。

  • パーティション ビューまたはパーティション テーブルのキー列が変更される場合
  • 複数の行が変更され、定数以外の値に対する一意でないクラスタ化インデックスのキーも更新される場合

**.**WRITE 句を使用して NULL 列を更新したり、 column_name の値を NULL に設定することはできません。

@Offset および @Length は、varbinary 型および varchar 型の場合はバイト数、nvarchar 型の場合は文字数で指定します。2 バイト文字セット (DBCS) の照合順序では、適切なオフセットが計算されます。

最高のパフォーマンスが得られるよう、8,040 バイトの倍数の単位でデータを挿入または更新することをお勧めします。

**.**WRITE 句で変更される列が OUTPUT 句で参照されている場合は、**deleted.**column_name の前イメージまたは **inserted.**column_name の後イメージのどちらかの列の完全な値が、テーブル変数内の指定された列に返されます。後述する例 G を参照してください。

他の文字型またはバイナリ データ型で **.**WRITE と同じ機能を実現するには、STUFF (Transact-SQL) を使用します。

text 型、ntext 型、および image 型の列を更新する

UPDATE で textntext、または image 型の列を変更する場合、NULL で列を更新しない限り、列が初期化され、有効なテキスト ポインタが割り当てられます。また、少なくとも 1 つのデータ ページが割り当てられます。

textntext、または image 型のデータの大きな部分を置換または変更するには、UPDATE ステートメントではなく WRITETEXT または UPDATETEXT ステートメントを使用してください。

ms177523.note(ja-jp,SQL.90).gif重要 :
ntexttext、および image の各データ型は、Microsoft SQL Server の将来のバージョンで削除される予定です。新しい開発作業ではこれらのデータ型の使用を避け、現在このデータ型を使用しているアプリケーションは変更を検討してください。代わりに、nvarchar(max)varchar(max)varbinary(max) を使用してください。詳細については、「大きな値のデータ型の使用」を参照してください。

UPDATE 操作で INSTEAD OF トリガを使用する

INSTEAD OF トリガが、テーブルに対する UPDATE 操作で定義されている場合は、UPDATE ステートメントの代わりにそのトリガが実行されます。以前のバージョンの SQL Server では、UPDATE およびその他のデータ変更ステートメントでサポートされているのは AFTER トリガのみです。FROM 句は、INSTEAD OF トリガが定義されているビューを直接または間接的に参照する UPDATE ステートメントでは指定できません。INSTEAD OF トリガの詳細については、「CREATE TRIGGER (Transact-SQL)」を参照してください。

変数と列を設定する

影響を受ける古い値と新しい値を示すために、UPDATE ステートメントの中で変数名を使用することは可能です。ただし、これは UPDATE ステートメントによって影響を受けるのが単一のレコードである場合のみに限定されています。UPDATE ステートメントで複数のレコードが影響を受ける場合に、各レコードの古い値と新しい値を返すためには、OUTPUT 句を使用してください。

権限

対象のテーブルに対する UPDATE 権限が必要です。UPDATE ステートメントで WHERE 句を指定する場合や、SET 句の expression でテーブル内の列を使用する場合は、SELECT 権限も必要です。

UPDATE 権限は、特に指定のない限り固定サーバー ロール sysadmin、固定データベース ロール db_owner、および固定データベース ロール db_datawriter のメンバと、テーブル所有者に与えられます。sysadmindb_owner、および db_securityadmin ロールのメンバ、およびテーブル所有者は、他のユーザーに権限を譲渡できます。

A. 単純な UPDATE ステートメントを使用する

次の例は、更新する行の指定に WHERE 句が使用されなかった場合に、すべての行がどのように影響を受けるかを示します。

この例では、SalesPerson テーブルのすべての行の Bonus 列、CommissionPct 列、および SalesQuota 列の値を更新します。

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

B. UPDATE ステートメントを WHERE 句と共に使用する

次の例では、WHERE 句を使用して更新する行を指定します。たとえば、Adventure Works Cycles 社は、自転車のモデル Road-250 について、赤と黒の 2 色を販売しています。この会社は、このモデルの赤をメタリックの赤に変更することに決めました。次のステートメントは、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

C. 別のテーブルの情報を使用して UPDATE ステートメントを実行する

次の例では、SalesOrderHeader テーブルの最新の売上高を反映するように SalesPerson テーブルの SalesYTD 列を変更します。

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

前の例では、特定の日付の指定された営業部員の売り上げは 1 つのみ記録され、更新が最新であるということを前提にしています。指定された営業部員に対し、同じ日に 2 つ以上の売り上げが記録される場合は、前の例は正しく動作しません。この場合、エラーなしで実行されますが、実際に同じ日に登録された売り上げ件数に関係なく、1 つの売り上げのみを使用して SalesYTD の値が更新されます。これは、1 つの UPDATE ステートメントで同じ行を 2 回更新しないためです。

指定された営業部員の同じ日の売り上げが 2 件以上発生する場合は、次の例のように、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

D. UPDATE ステートメントを TOP 句と共に使用する

次の例では、Employee テーブル内のランダムな 10 個の行について、VacationHours 列を 25% 増しに更新します。

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

E. UPDATE ステートメントを OUTPUT 句と共に使用する

次の例では、Employee テーブル内の最初の 10 個の行について、VacationHours 列を 25% 増しに更新します。OUTPUT 句は、UPDATE を適用する前の DELETED.VacationHours 列の VacationHours の値と、INSERTED.VacationHours 列の更新後の値を @MyTableVartable 変数に返します。

後続の 2 つの SELECT ステートメントは、@MyTableVar 内の値と、Employee テーブルでの更新操作の結果を返します。INSERTED.ModifiedDate 列の値は、Employee テーブルの ModifiedDate の値とは異なる点に注意してください。これは、Employee テーブルに、ModifiedDate の値を最新の日付に更新する AFTER UPDATE トリガが定義されているためです。ただし、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

F. UPDATE を WITH common_table_expression 句と共に使用する

次の例は、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

G. UPDATE を .WRITE 句と共に使用して、nvarchar(max) 列のデータを変更する

次の例では、**.**WRITE 句を使用して、Production.Document テーブルの nvarchar(max) 型の DocumentSummary 列の値を部分的に更新します。置換する語、既存データ内で置換される語の開始位置 (オフセット)、置換する文字数 (長さ) を指定することにより、components という語が、features という語で置換されます。またこの例では、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

H. 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

I. UPDATE を OPENROWSET と共に使用し、varbinary(max) 列を変更する

次の例では、varbinary(max) 列に格納されている既存のイメージを、新しいイメージで置換します。OPENROWSET 関数を BULK オプションと共に使用し、列にイメージを読み込みます。この例では、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 の参考資料の入手