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 運算式所參考的資料列並不依照任何順序來排列。

    TOP 中用來分隔 expression 的括號,在 INSERT、UPDATE 和 DELETE 陳述式中是必要的。如需詳細資訊,請參閱<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_name 必須在 table_or view_name 中。無法更新識別資料行。
  • expression
    這是傳回單一值的變數、常值、運算式或子選取陳述式 (括在括號內)。expression 傳回的值會取代 column_name 或 *@variable* 中現有的值。
  • DEFAULT
    指定資料行所定義的預設值要取代資料行中現有的值。如果資料行沒有預設值,且定義成允許空值,您可以利用這個方式,將資料行改成 NULL。
  • udt_column_name
    這是使用者自訂類型資料行。
  • property_name | field_name
    這是使用者自訂類型的公用屬性或公用資料成員。
  • method_name**(**argument [ ,... n] )
    這是 udt_column_name 有一或多個引數的非靜態公用 mutator 方法。
  • **.**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*,且會在指定的 *@Offset* 截斷 column_name 中的值。

    @Offset* 是 column_name 值中的起點,而 expression 則是在該起點寫入的。@Offset* 是以零為基底的序數位置,也是 bigint,且不能是負數。如果 *@Offset* 是 NULL,更新作業會在現有 column_name 值的結尾附加 expression,且會忽略 *@Length*。如果 @Offset 大於 column_name 值的長度,Microsoft SQL Server 2005 Database Engine 會傳回一則錯誤。如果 *@Offset* 加上 *@Length* 超出資料行基礎值的結尾,就會刪除到值的最後一個字元。如果 *@Offset* 加上 LEN(expression) 大於基礎的宣告大小,就會引發錯誤。

    *@Length* 是資料行中的區段長度,開頭為 @Offset*,它會由 expression 所取代。@Length* 是 bigint,且不能是負數。如果 *@Length* 是 NULL,更新作業會移除從 *@Offset* 到 column_name 值結尾的所有資料。

    如需詳細資訊,請參閱「備註」一節。

  • **@**variable
    這是設定為 expression 傳回的值之宣告變數。

    SET **@**variable = column = expression 會將變數設成與資料行相同的值。這有別於 SET **@**variable = columncolumn = expression,它會將變數設成資料行更新之前的值。

  • <OUTPUT_Clause>
    在 UPDATE 作業中,傳回更新資料或以更新資料為基礎的運算式。任何目標是遠端資料表或檢視的 DML 陳述式都不支援 OUTPUT 子句。如需詳細資訊,請參閱<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 ] )
    指定利用最佳化工具提示來自訂 Database Engine 處理陳述式的方式。如需詳細資訊,請參閱<查詢提示 (Transact-SQL)>。

備註

記錄 UPDATE 陳述式;不過,利用 **.**WRITE 子句來進行大數值資料類型的部分更新,只會有最少記錄。如需詳細資訊,請參閱下面的「更新大數值資料類型」。

只有在所修改的資料表是一個 table 變數時,才能在使用者自訂函數主體中使用 UPDATE 陳述式。

如果資料列的更新違反條件約束或規則、違反資料行的 NULL 設定,或新值是不相容的資料類型,便會取消陳述式,傳回錯誤,且不會更新任何記錄。

當 UPDATE 陳述式在運算式評估期間發生算術錯誤 (溢位、除以零或區域錯誤) 時,便不會進行更新。批次的其餘部分也不會執行,且會傳回錯誤訊息。

如果參與叢集索引的一或多個資料行的更新使叢集索引和資料列的大小超出 8,060 位元組,更新就會失敗,且會傳回錯誤訊息。

如果 UPDATE 陳述式在更新叢集索引鍵及一或多個 textntextimage 資料行時,可以變更多個資料列,以完整取代值的方式來執行這些資料列的部分更新。

所有 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

如果 UPDATE 陳述式包括 FROM 子句,且這個 FROM 子句的指定方式並非每個更新的資料行項目都只能使用一個值,也就是說,如果 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 的方法來執行更新。下列範例會叫用名稱為 SetXYPoint 類型之 mutator 方法。這會更新類型執行個體的狀態。

    UPDATE Cities
    SET Location.SetXY(23.5, 23.5)
    WHERE Name = 'Anchorage';
    
    ms177523.note(zh-tw,SQL.90).gif附註:
    如果在 Transact-SQL Null 值上呼叫了 mutator 方法,或是 mutator 方法所產生的新值是 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 更新只會有最少的記錄。當更新現有的值時,不會使用最少的記錄。如需詳細資訊,請參閱<最低限度記錄作業>。

當 UPDATE 陳述式造成下列情況時,SQL Server 2005 Database Engine 會將部分更新轉換成完整更新:

  • 變更資料分割檢視或資料表的索引鍵資料行。
  • 修改多個資料列,同時也將不是唯一的叢集索引之索引鍵更新成非常數值。

您不能利用 **.**WRITE 子句來更新 NULL 資料行,或將 column_name 的值設成 NULL。

varbinaryvarchar 資料類型的 *@Offset* 和 *@Length* 是以位元組來指定,nvarchar 資料類型則是以字元來指定。雙位元組字元集 (DBCS) 定序會計算適當的位移。

若要有最佳效能,我們建議您以 8040 位元組倍數的片段大小來插入或更新資料。

如果在 OUTPUT 子句中參考 **.**WRITE 子句所修改的資料行,就會將資料行的完整值,不論是在 **deleted.**column_name 中的影像之前,或在 **inserted.**column_name 中的影像之後,傳回資料表變數中的指定資料行。請參閱下面的 G 範例。

若要利用其他字元或二進位資料類型來完成 **.**WRITE 的相同功能,請使用 STUFF (Transact-SQL)

更新 text、ntext 和 image 資料行

除非用 NULL 更新資料行,否則,利用 UPDATE 來修改 textntextimage 資料行會初始化資料行、將有效的文字指標指派給它,再配置至少一個資料頁面。

若要取代或修改 textntextimage 資料的大型區塊,請利用 WRITETEXTUPDATETEXT 來取代 UPDATE 陳述式。

ms177523.note(zh-tw,SQL.90).gif重要事項:
未來的 Microsoft SQL Server 版本將移除 ntexttextimage 等資料類型。請避免在新的開發工作中使用這些資料類型,並規劃修改目前在使用這些資料類型的應用程式。請改用 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 角色的成員,以及資料表擁有者,可以將權限轉讓給其他使用者。

範例

A. 使用簡單的 UPDATE 陳述式

下列範例會顯示當沒有用 WHERE 子句來指定要更新的一或多個資料列時,能夠如何影響所有資料列。

這個範例會更新 SalesPerson 資料表中所有資料列的 BonusCommissionPctSalesQuota 資料行值。

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. 搭配 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

C. 搭配另一份資料表的資訊來使用 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

D. 搭配 TOP 子句來使用 UPDATE

下列範例會將 Employee 資料表中 10 個隨機資料列的 VacationHours 資料行更新 25%。

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

E. 搭配 OUTPUT 子句使用 UPDATE

下列範例會將 Employee 資料表前 10 個資料列的 VacationHours 資料行更新 25%。OUTPUT 子句會將在 DELETED.VacationHours 資料行中套用 UPDATE 陳述式之前便已存在的 VacationHours 值,以及 INSERTED.VacationHours 資料行中更新的值傳回 @MyTableVartable 變數。

之後的兩個 SELECT 陳述式會傳回 @MyTableVar 中的值,以及 Employee 資料表中更新作業的結果。請注意,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

F. 搭配 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

G. 搭配 .WRITE 子句來使用 UPDATE,以修改 nvarchar(max) 資料行中的資料

下列範例會利用 **.**WRITE 子句來更新 DocumentSummary (Production.Document資料表中的 nvarchar(max) 資料行) 中的部分值。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. 搭配 .WRITE 來使用 UPDATE,以新增和移除 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. 搭配 OPENROWSET 來使用 UPDATE,以修改 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)
Text 和 Image 函數 (Transact-SQL)
WITH common_table_expression (Transact-SQL)

其他資源

更新資料表中的資料

說明及資訊

取得 SQL Server 2005 協助