Condividi tramite


UPDATE (Transact-SQL)

Modifica i dati esistenti in una o più colonne di una tabella o una vista in SQL Server 2008.

Icona di collegamento a un argomentoConvenzioni della sintassi Transact-SQL

Sintassi

[ WITH common_table_expression [...n] ]
UPDATE 
    [ TOP (expression) [ PERCENT ] ] 
    { { table_alias | <object> | rowset_function_limited 
        [ WITH (table_hint_limited [ ...n ] ) ]
      }
      | @table_variable
    }
    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
          | column_name { += | -= | *= | /= | %= | &= | ^= | |= } expression
          | @variable { += | -= | *= | /= | %= | &= | ^= | |= } expression
          | @variable=column_name { += | -= | *= | /= | %= | &= | ^= | |= } expression
        } [ ,...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
}

Argomenti

  • WITH common_table_expression
    Specifica una vista o un set di risultati denominato temporaneo, noto anche come espressione di tabella comune, definito nell'ambito di un'istruzione UPDATE. Il set di risultati deriva da un'istruzione SELECT e vi viene fatto riferimento tramite l'istruzione UPDATE. Per ulteriori informazioni, vedere WITH common_table_expression (Transact-SQL).

  • TOP ( expression) [ PERCENT ]
    Specifica il numero o la percentuale di righe che verranno aggiornate. expression può essere un numero o una percentuale delle righe. Le righe cui viene fatto riferimento nell'espressione TOP di un'istruzione INSERT, UPDATE, MERGE o DELETE non sono ordinate.

    Le parentesi che delimitano expression nell'espressione TOP sono necessarie nelle istruzioni INSERT, UPDATE, MERGE e DELETE. Per ulteriori informazioni, vedere TOP (Transact-SQL).

  • table_alias
    Alias specificato nella clausola FROM che rappresenta la tabella o la vista da cui vengono aggiornate le righe.

  • server_name
    Nome del server collegato in cui si trova la tabella o la vista. È possibile specificare server_name come nome del server collegato oppure con la funzione OPENDATASOURCE.

    Quando server_name viene specificato come server collegato, database_name e schema_name sono obbligatori. Quando server_name viene specificato con OPENDATASOURCE, database_name e schema_name possono non essere validi per tutte le origini dati ed essere soggetti alle funzionalità del provider OLE DB tramite cui viene effettuato l'accesso all'oggetto remoto. Per ulteriori informazioni, vedere Query distribuite.

  • database_name
    Nome del database.

  • schema_name
    Nome dello schema a cui appartiene la tabella o la vista.

  • table_or view_name
    Nome della tabella o della vista da cui si desidera aggiornare le righe.

    È necessario che la vista specificata nell'argomento table_or_view_name sia aggiornabile e includa un riferimento a un'unica tabella di base nella clausola FROM della definizione della vista. Per ulteriori informazioni sulle viste aggiornabili, vedere CREATE VIEW (Transact-SQL).

  • rowset_function_limited
    Funzione OPENQUERY o OPENROWSET. L'utilizzo di queste funzioni è soggetto alle funzionalità del provider OLE DB che accede all'oggetto remoto. Per ulteriori informazioni, vedere Query distribuite.

  • WITH (table_hint_limited)
    Specifica uno o più hint di tabella consentiti per la tabella di destinazione. Gli hint di tabella eseguono l'override del comportamento predefinito di Query Optimizer per la durata dell'istruzione UPDATE. Le opzioni NOLOCK e READUNCOMMITTED non sono consentite. Per ulteriori informazioni sugli hint di tabella, vedere Hint di tabella (Transact-SQL).

  • @table\_variable
    Indica una variabile table come origine di tabella.

  • SET
    Indica l'elenco dei nomi di colonna o di variabile da aggiornare.

  • column_name
    Colonna contenente i dati da modificare. column_name deve esistere in table_or view_name. Non è possibile aggiornare le colonne Identity.

  • expression
    Variabile, valore letterale, espressione o istruzione sub-SELECT racchiusa tra parentesi che restituisce un valore singolo. Il valore restituito da expression sostituisce il valore esistente in column_name o @variable.

    [!NOTA]

    Quando si fa riferimento ai tipi di dati dei caratteri Unicode nchar, nvarchar e ntext, "expression" deve essere preceduto dalla lettera maiuscola "N". Se la lettera "N" non è specificata, in SQL Server la stringa viene convertita in base alla tabella codici corrispondente alle regole di confronto predefinite del database o della colonna. Tutti i caratteri non trovati nella tabella codici vengono persi. Per ulteriori informazioni, vedere Utilizzo dei dati Unicode.

  • DEFAULT
    Specifica che il valore predefinito impostato per la colonna deve sostituire il valore esistente all'interno della colonna. Questo argomento consente inoltre di modificare il valore della colonna in NULL se la colonna non dispone di un valore predefinito e ammette valori Null.

  • { += | -= | *= | /= | %= | &= | ^= | |= }
    Operatore composto utilizzato per eseguire un'operazione e impostare il valore originale sul risultato dell'operazione.

    +=    Aggiunta e assegnazione

    -=    Sottrazione e assegnazione

    *=    Moltiplicazione e assegnazione

    /=    Divisione e assegnazione

    %=    Modulo e assegnazione

    &=     AND bit per bit e assegnazione

    ^=    XOR bit per bit e assegnazione

    |=    OR bit per bit e assegnazione

    Per ulteriori informazioni, vedere Operatori composti (Transact-SQL).

  • udt_column_name
    Colonna definita dall'utente.

  • property_name | field_name
    Proprietà pubblica o membro dei dati pubblici di un tipo definito dall'utente. È necessario che l'espressione che fornisce il valore possa essere convertita in modo implicito nel tipo della proprietà.

    Per modificare proprietà diverse della stessa colonna con tipo definito dall'utente, applicare più istruzioni UPDATE o richiamare un metodo mutatore del tipo.

  • method_name( argument [ ,... n] )
    Metodo mutatore pubblico non statico di udt_column_name che accetta uno o più argomenti. SQL Server restituisce un errore se un metodo mutatore viene richiamato su un valore Null Transact-SQL oppure se un nuovo valore prodotto da un metodo mutatore è Null.

  • .WRITE (expression,@Offset, @Length)
    Specifica che una sezione del valore di column_name deve essere modificata. expression sostituisce le unità @Length a partire da @Offset di column_name. Solo le colonne di tipo varchar(max), nvarchar(max) o varbinary(max) possono essere specificate con questa clausola. column_name non può essere NULL e non può essere qualificato con un nome o alias di tabella.

    expression è il valore che viene copiato in column_name. expression deve restituire il tipo o essere in grado di eseguire il cast esplicito al tipo column_name. Se il valore di expression è impostato su NULL, @Length viene ignorato e il valore in column_name viene troncato in corrispondenza dell'offset specificato in @Offset.

    @Offset è il punto di partenza nel valore di column_name in corrispondenza del quale viene scritta l'espressione expression. @Offset è una posizione ordinale in base zero, è di tipo bigint e non può essere un valore negativo. Se @Offset è NULL, l'operazione di aggiornamento accoda expression al termine del valore column_name e @Length viene ignorato. Se @Offset è maggiore della lunghezza del valore column_name, il Motore di database restituisce un errore. Se @Offset più @Length supera la fine del valore sottostante nella colonna, l'eliminazione viene applicata fino all'ultimo carattere del valore. Se @Offset più LEN(expression) è maggiore rispetto alle dimensioni dichiarate sottostanti, viene generato un errore.

    @Length è la lunghezza della sezione nella colonna, a partire da @Offset, che viene sostituita da expression. @Length è di tipo bigint e non può essere un numero negativo. Se @Length è NULL, l'operazione di aggiornamento rimuove tutti i dati da @Offset fino alla fine del valore column_name.

    Per ulteriori informazioni, vedere "Aggiornamento di tipi di dati LOB (Large Object)".

  • @variable
    Variabile dichiarata impostata sul valore restituito da expression.

    SET @variable = column = expression imposta la variabile sullo stesso valore della colonna, a differenza di SET @variable = column, column = expression, che imposta la variabile sul valore precedente all'aggiornamento della colonna.

  • OUTPUT_clause
    Restituisce dati aggiornati o espressioni basate su di essi come parte dell'operazione UPDATE. La clausola OUTPUT non è supportata nelle istruzioni DML destinate a viste partizionate locali, viste partizionate distribuite oppure tabelle o viste remote. Per ulteriori informazioni, vedere Clausola OUTPUT (Transact-SQL).

  • FROM table_source
    Specifica che una tabella, vista o origine di tabella derivata viene utilizzata per fornire i criteri per l'operazione di aggiornamento. Per ulteriori informazioni, vedere FROM (Transact-SQL).

    Se l'oggetto da aggiornare coincide con l'oggetto specificato nella clausola FROM e la clausola FROM include un solo riferimento all'oggetto, non è necessario specificare un alias di oggetto. Se l'oggetto da aggiornare è specificato più di una volta nella clausola FROM, un solo riferimento all'oggetto non deve specificare un alias della tabella. Tutti gli altri riferimenti all'oggetto nella clausola FROM devono includere l'alias dell'oggetto.

  • WHERE
    Specifica le condizioni che limitano le righe da aggiornare. Sono disponibili due tipi di aggiornamento basati sul tipo di clausola WHERE:

    • Gli aggiornamenti con ricerca specificano una condizione di ricerca che qualifica le righe da eliminare.

    • Gli aggiornamenti posizionati utilizzano la clausola CURRENT OF per specificare un cursore. L'operazione di aggiornamento viene in questo caso eseguita nella posizione corrente del cursore. Se si esegue un aggiornamento posizionato tramite la clausola WHERE CURRENT OF, viene aggiornata la riga singola che corrisponde alla posizione corrente del cursore. Questa operazione può essere più accurata di un aggiornamento con ricerca che utilizza una clausola WHERE <search_condition> per qualificare le righe da aggiornare. Un aggiornamento con ricerca modifica più righe se le condizioni di ricerca non identificano una singola riga in modo univoco.

  • search_condition
    Specifica la condizione che le righe da aggiornare devono soddisfare. La condizione di ricerca può inoltre essere rappresentata dalla condizione per un join. Non sono previsti limiti per il numero di predicati che è possibile includere in una condizione di ricerca. Per ulteriori informazioni sulle condizioni e i predicati di ricerca, vedere Condizione di ricerca (Transact-SQL).

  • CURRENT OF
    Indica che l'aggiornamento viene eseguito nella posizione corrente del cursore specificato.

  • GLOBAL
    Specifica che l'argomento cursor_name fa riferimento a un cursore globale.

  • cursor_name
    Nome del cursore aperto dal quale deve essere eseguita l'operazione di recupero. Se esistono sia un cursore globale sia un cursore locale denominati cursor_name, questo argomento fa riferimento al cursore globale se è stato specificato l'argomento GLOBAL. In caso contrario, fa riferimento al cursore locale. Il cursore deve consentire operazioni di aggiornamento.

  • cursor_variable_name
    Nome di una variabile di cursore. cursor_variable_name deve fare riferimento a un cursore che consente operazioni di aggiornamento.

  • OPTION (query_hint [ ,... n ] )
    Specifica che vengono utilizzati hint di ottimizzazione per personalizzare la modalità di elaborazione dell'istruzione nel Motore di database. Per ulteriori informazioni, vedere Hint per la query (Transact-SQL).

Procedure consigliate

Nelle istruzioni UPDATE è possibile utilizzare nomi di variabili per indicare il valore da aggiornare e il valore in base a cui eseguire l'aggiornamento. I nomi di variabili tuttavia devono essere utilizzati solo quando l'istruzione UPDATE è relativa a un unico record. In caso contrario, utilizzare la clausola OUTPUT per restituire i valori vecchi e nuovi per ogni record.

Prestare attenzione nella specifica della clausola FROM per fornire i criteri per l'operazione di aggiornamento. I risultati di un'istruzione UPDATE sono indefiniti se l'istruzione include una clausola FROM non specificata in modo che sia disponibile un unico valore per ogni occorrenza di colonna che viene aggiornata, ovvero se l'istruzione UPDATE non è deterministica. Si potrebbero verificare risultati imprevisti. Ad esempio, nell'istruzione UPDATE dello script riportato di seguito entrambe le righe della tabella Table1 soddisfano le condizioni della clausola FROM nell'istruzione UPDATE, ma non viene specificato quale riga di Table1 viene utilizzata per aggiornare la riga nella tabella 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 PRIMARY KEY 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), (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;

Lo stesso problema può verificarsi quando si combinano le clausole FROM e WHERE CURRENT OF. Nell'esempio seguente, entrambe le righe nella tabella Table2 soddisfano le condizioni della clausola FROM nell'istruzione UPDATE. Non viene specificato tuttavia quale riga di Table2 viene utilizzata per l'aggiornamento della riga nella tabella 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), (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

Tipi di dati

Tutte le colonne di tipo char e nchar vengono riempite con caratteri nulli a destra fino a raggiungere la lunghezza definita.

Se l'opzione ANSI_PADDING è impostata su OFF, tutti gli spazi finali vengono rimossi dai dati inseriti nelle colonne varchar e nvarchar, tranne nel caso di stringhe che includono solo spazi, le quali vengono troncate come stringhe vuote. Se l'opzione ANSI_PADDING è impostata su ON, vengono inseriti spazi finali. Il driver ODBC di Microsoft SQL Server e il provider OLE DB per SQL Server impostano automaticamente l'opzione ANSI_PADDING su ON per ogni connessione. Questa opzione può essere configurata in origini dati ODBC oppure impostando gli attributi o le proprietà della connessione. Per ulteriori informazioni, vedere SET ANSI_PADDING (Transact-SQL).

Aggiornamento dei tipi di dati per valori di grandi dimensioni

Utilizzare la clausola .WRITE (expression, @Offset,@Length) per eseguire un aggiornamento parziale o completo dei tipi di dati varchar(max), nvarchar(max) e varbinary(max). Ad esempio, un aggiornamento parziale di una colonna di tipo varchar(max) potrebbe eliminare o modificare solo i primi 200 caratteri della colonna, mentre un aggiornamento completo elimina o modifica tutti i dati nella colonna.

Per prestazioni ottimali, è consigliabile inserire o aggiornare i dati in dimensioni di blocco multiple di 8040 byte.

In Motore di database un aggiornamento parziale viene convertito in aggiornamento completo quando l'istruzione UPDATE provoca una di queste azioni:

  • modifica una colonna chiave della vista o tabella partizionata

  • modifica più di una riga e allo stesso tempo aggiorna la chiave di un indice cluster non univoco ad un valore non costante.

Non è possibile utilizzare la clausola .WRITE per aggiornare una colonna NULL o impostare il valore di column_name su NULL.

I valori di @Offset e @Length vengono specificati in byte per i tipi di dati varbinary e varchar e in caratteri per il tipo di dati nvarchar. Gli offset appropriati vengono calcolati per le regole di confronto DBCS (Double-Byte Character Set).

Se in una clausola OUTPUT si fa riferimento alla colonna modificata dalla clausola .WRITE, il valore completo della colonna, ovvero l'immagine precedente all'aggiornamento in deleted.column_name oppure l'immagine successiva all'aggiornamento in inserted.column_name, viene restituito nella colonna specificata nella variabile di tabella.

Per raggiungere la stessa funzionalità di .WRITE con altri tipi di dati character o binary utilizzare STUFF (Transact-SQL).

Aggiornamento di dati FILESTREAM

È possibile utilizzare l'istruzione UPDATE per aggiornare un campo FILESTREAM a un valore null, a un valore vuoto o a una quantità di dati inline relativamente piccola. Tuttavia, una grande quantità di dati viene trasmessa in modo più efficace in un file mediante l'utilizzo di interfacce Win32. Quando si aggiorna un campo FILESTREAM, si modificano i dati BLOB sottostanti nel file system. Quando un campo FILESTREAM viene impostato su NULL, i dati BLOB associati al campo vengono eliminati. Non è possibile utilizzare .WRITE() per eseguire aggiornamenti parziali ai dati FILESTREAM. Per ulteriori informazioni, vedere Panoramica di FILESTREAM.

Aggiornamento di colonne text, ntext e image

Se si modifica una colonna di tipo text, ntext o image tramite l'istruzione UPDATE, la colonna viene inizializzata, viene associata a un puntatore di testo valido e viene allocata almeno una pagina di dati, a meno che non si esegua l'aggiornamento della colonna con NULL. Se un'istruzione UPDATE modifica più righe durante l'aggiornamento della chiave di clustering e di una o più colonne di tipo text, ntext o image, l'aggiornamento parziale di queste colonne viene eseguito come sostituzione completa dei valori.

Per sostituire o modificare grandi quantità di dati di tipo text, ntext o image, utilizzare le istruzioni WRITETEXT o UPDATETEXT invece dell'istruzione UPDATE.

Nota importanteImportante

I tipi di dati ntext, text e image verranno rimossi in una delle prossime versioni di MicrosoftSQL Server. Evitare di utilizzare questi tipi di dati in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni che attualmente li utilizzano. Utilizzare nvarchar(max), varchar(max) e varbinary(max) in alternativa. Per ulteriori informazioni, vedere Utilizzo di tipi di dati per valori di grandi dimensioni.

Gestione degli errori

È possibile implementare la gestione degli errori per l'istruzione UPDATE specificando l'istruzione in un costrutto TRY…CATCH. Per ulteriori informazioni, vedere Utilizzo di TRY...CATCH in Transact-SQL.

Se un'operazione di aggiornamento in una riga viola un vincolo o una regola, viola l'impostazione relativa al supporto dei valori Null per la colonna oppure il nuovo valore è un tipo di dati incompatibile, l'istruzione viene annullata, viene restituito un errore e non viene aggiornato alcun record.

Quando un'istruzione UPDATE rileva un errore aritmetico (un errore di overflow, una divisione per zero o un errore di dominio) durante la valutazione di un'espressione, l'aggiornamento non viene eseguito. La parte rimanente del batch non viene eseguita e viene visualizzato un messaggio di errore.

Se dopo un aggiornamento a una o più colonne che fanno parte di un indice cluster le dimensioni dell'indice cluster e della riga superano gli 8.060 byte, l'aggiornamento non viene eseguito correttamente e viene restituito un messaggio di errore.

Interoperabilità

Le istruzioni UPDATE sono consentite all'interno delle funzioni definite dall'utente solo se la tabella da modificare è una variabile di tabella.

Quando viene definito un trigger INSTEAD OF in azioni UPDATE eseguite su una tabella, viene eseguito il trigger anziché l'istruzione UPDATE. Nelle versioni precedenti di SQL Server sono supportati solo i trigger AFTER definiti in UPDATE e altre istruzioni di modifica dei dati.

Limitazioni e restrizioni

La clausola FROM non può essere specificata in un'istruzione UPDATE in cui si fa riferimento diretto o indiretto a una vista in cui è definito un trigger INSTEAD OF. Per ulteriori informazioni sui trigger INSTEAD OF, vedere CREATE TRIGGER (Transact-SQL).

L'impostazione dell'opzione SET ROWCOUNT viene ignorata per le istruzioni UPDATE eseguite su tabelle remote e viste partizionate locali e remote. L'utilizzo di SET ROWCOUNT non avrà effetto sulle istruzioni UPDATE nella prossima versione di SQL Server. Non utilizzare SET ROWCOUNT con le istruzioni UPDATE in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni in cui è attualmente implementata per utilizzare la sintassi TOP.

Quando un'espressione di tabella comune (CTE) è la destinazione di un'istruzione UPDATE, tutti i riferimenti a tale espressione nell'istruzione devono corrispondere. Se, ad esempio, alla CTE è assegnato un alias nella clausola FROM, l'alias deve essere utilizzato per tutti gli altri riferimenti alla CTE. Sono necessari riferimenti CTE non ambigui perché una CTE non dispone di un ID oggetto utilizzato da SQL Server per riconoscere la relazione implicita tra l'oggetto e il relativo alias. Senza questa relazione è possibile che il piano di query produca un comportamento del join e risultati della query imprevisti. Negli esempi seguenti vengono illustrati i metodi corretti ed errati della definizione di una CTE quando questa è l'oggetto di destinazione dell'operazione di aggiornamento.

USE tempdb;
GO
-- UPDATE statement with CTE references that are correctly matched.
DECLARE @x TABLE (ID int, Value int);
DECLARE @y TABLE (ID int, Value int);
INSERT @x VALUES (1, 10), (2, 20);
INSERT @y VALUES (1, 100),(2, 200);

WITH cte AS (SELECT * FROM @x)
UPDATE x -- cte is referenced by the alias.
SET Value = y.Value
FROM cte AS x  -- cte is assigned an alias.
INNER JOIN @y AS y ON y.ID = x.ID;
SELECT * FROM @x;
GO

Set di risultati:

ID     Value

------ -----

1      100

2      200

(2 row(s) affected)

-- UPDATE statement with CTE references that are incorrectly matched.
USE tempdb;
GO
DECLARE @x TABLE (ID int, Value int);
DECLARE @y TABLE (ID int, Value int);
INSERT @x VALUES (1, 10), (2, 20);
INSERT @y VALUES (1, 100),(2, 200);

WITH cte AS (SELECT * FROM @x)
UPDATE cte   -- cte is not referenced by the alias.
SET Value = y.Value
FROM cte AS x  -- cte is assigned an alias.
INNER JOIN @y AS y ON y.ID = x.ID; 
SELECT * FROM @x; 
GO

Set di risultati:

ID     Value

------ -----

1      100

2      100

(2 row(s) affected)

Comportamento di registrazione

L'istruzione UPDATE viene registrata completamente, tuttavia gli aggiornamenti .WRITE che inseriscono o accodano nuovi dati vengono registrati in maniera minima se il modello di recupero del database è impostato su registrazione minima delle operazioni bulk oppure su registrazione minima. La registrazione minima non è utilizzata quando si utilizza .WRITE per aggiornare i valori esistenti. Per ulteriori informazioni, vedere Operazioni per cui è possibile eseguire la registrazione minima.

Protezione

Autorizzazioni

Le autorizzazioni UPDATE sono necessarie nella tabella di destinazione. Se l'istruzione UPDATE include una clausola WHERE oppure l'argomento expression nella clausola SET utilizza una colonna della tabella, sono inoltre necessarie le autorizzazioni per l'esecuzione dell'istruzione SELECT nella tabella da aggiornare.

Le autorizzazioni UPDATE vengono concesse per impostazione predefinita ai membri del ruolo predefinito del server sysadmin, ai membri dei ruoli predefiniti del database db_owner e db_datawriter e al proprietario della tabella. I membri dei ruoli sysadmin, db_owner e db_securityadmin e il proprietario della tabella possono trasferire le autorizzazioni ad altri utenti.

Esempi

Categoria

Elementi di sintassi inclusi

Sintassi di base

UPDATE

Limitazione delle righe da aggiornare

WHERE • TOP • espressione di tabella comune WITH • WHERE CURRENT OF

Impostazione di valori di colonna

valori calcolati • operatori composti • valori predefiniti • sottoquery

Specifica di oggetti di destinazione diversi dalle tabelle standard

viste • variabili di tabella • alias di tabella

Aggiornamento di dati basati su dati di altre tabelle

FROM

Aggiornamento di righe in una tabella remota

server collegato • OPENQUERY • OPENDATASOURCE

Aggiornamento di tipi di dati LOB (Large Object)

.WRITE • OPENROWSET

Aggiornamento di tipi definiti dall'utente

tipi definiti dall'utente

Override del comportamento predefinito di Query Optimizer tramite hint

hint di tabella • hint per la query

Acquisizione dei risultati dell'istruzione UPDATE

clausola OUTPUT

Utilizzo di UPDATE in altre istruzioni

stored procedure • TRY…CATCH

Sintassi di base

Negli esempi di questa sezione vengono illustrate le funzionalità di base dell'istruzione UPDATE tramite la sintassi minima richiesta.

A. Esecuzione di un'istruzione UPDATE semplice

In questo esempio viene aggiornata una singola colonna per tutte le righe della tabella Person.Address.

USE AdventureWorks;
GO
UPDATE Person.Address
SET ModifiedDate = GETDATE();

B. Aggiornamento di più colonne

In questo esempio vengono aggiornati i valori nelle colonne Bonus, CommissionPct e SalesQuota per tutte le righe nella tabella SalesPerson.

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

Limitazione delle righe da aggiornare

Negli esempi di questa sezione vengono illustrate le modalità da utilizzare per limitare il numero di righe interessate dall'istruzione UPDATE.

A. Utilizzo della clausola WHERE

Nell'esempio seguente viene utilizzata la clausola WHERE per specificare le righe da aggiornare. L'istruzione aggiorna il valore nella colonna Color della tabella Production.Product per tutte le righe che contengono il valore esistente "Red" nella colonna Color e che contengono un valore nella colonna Name che inizia con "Road-250".

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

B. Utilizzo della clausola TOP

Negli esempi seguenti viene utilizzata la clausola TOP per limitare il numero di righe modificate in un'istruzione UPDATE. Quando si utilizza una clausola TOP (n) con l'istruzione UPDATE, l'operazione di aggiornamento viene eseguita su una selezione casuale di un numero n di righe. Nell'esempio seguente viene aggiornata la colonna VacationHours del 25% per 10 righe casuali nella tabella Employee.

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

Se è necessario utilizzare la clausola TOP per applicare gli aggiornamenti in un ordine cronologico significativo, sarà necessario utilizzare questa clausola insieme a ORDER BY in un'istruzione sub-SELECT. Nell'esempio seguente le ore di ferie dei 10 dipendenti vengono aggiornate con le prime date di assunzione.

UPDATE HumanResources.Employee
SET VacationHours = VacationHours + 8
FROM (SELECT TOP 10 EmployeeID FROM HumanResources.Employee
     ORDER BY HireDate ASC) AS th
WHERE HumanResources.Employee.EmployeeID = th.EmployeeID;
GO

C. Utilizzo della clausola WITH common_table_expression

Nell'esempio seguente il valore VacationHours viene aggiornato del 25% per tutti i dipendenti che sono subordinati direttamente o indirettamente a ManagerID12. L'espressione di tabella comune restituisce un elenco gerarchico dei dipendenti che sono subordinati direttamente a ManagerID12 e dei dipendenti che sono subordinati a questi dipendenti, e così via. Vengono modificate solo le righe restituite dall'espressione di tabella comune. Per ulteriori informazioni sulle espressioni di tabella comuni ricorsive, vedere Query ricorsive tramite espressioni di tabella comuni.

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

D. Utilizzo della clausola WHERE CURRENT OF

Nell'esempio seguente viene utilizzata la clausola WHERE CURRENT OF per aggiornare solo la riga su cui è posizionato il cursore. Se un cursore è basato su un join, viene modificato solo il valore table_name specificato nell'istruzione UPDATE. Le altre tabelle interessate dal cursore rimangono invariate.

USE AdventureWorks;
GO
DECLARE complex_cursor CURSOR FOR
    SELECT a.EmployeeID
    FROM HumanResources.EmployeePayHistory AS a
    WHERE RateChangeDate <> 
         (SELECT MAX(RateChangeDate)
          FROM HumanResources.EmployeePayHistory AS b
          WHERE a.EmployeeID = b.EmployeeID) ;
OPEN complex_cursor;
FETCH FROM complex_cursor;
UPDATE HumanResources.EmployeePayHistory
SET PayFrequency = 2 
WHERE CURRENT OF complex_cursor;
CLOSE complex_cursor;
DEALLOCATE complex_cursor;
GO

Impostazione di valori di colonna

Negli esempi di questa sezione viene illustrato l'aggiornamento delle colonne mediante valori calcolati, sottoquery e valori DEFAULT.

A. Specifica di un valore calcolato

Negli esempi seguenti vengono utilizzati valori calcolati in un'istruzione UPDATE. Nell'esempio viene raddoppiato il valore della colonna ListPrice per tutte le righe della tabella Product.

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

B. Specifica di un operatore composto

Nell'esempio seguente viene utilizzata la variabile @NewPrice per incrementare il prezzo di tutte le biciclette rosse aggiungendo 10 al prezzo corrente.

USE AdventureWorks;
GO
DECLARE @NewPrice int = 10;
UPDATE Production.Product
SET ListPrice += @NewPrice
WHERE Color = N'Red';
GO

Nell'esempio seguente viene utilizzato l'operatore composto += per aggiungere i dati ' - tool malfunction' al valore esistente nella colonna Name per le righe che contengono un valore ScrapReasonID compreso tra 10 e 12.

USE AdventureWorks;
GO
UPDATE Production.ScrapReason 
SET Name += ' - tool malfunction'
WHERE ScrapReasonID BETWEEN 10 and 12;

C. Specifica di una sottoquery nella clausola SET

Nell'esempio seguente viene utilizzata una sottoquery nella clausola SET per determinare il valore utilizzato per aggiornare la colonna. La sottoquery deve restituire solo un valore scalare, ovvero un solo valore per riga. Nell'esempio viene modificata la colonna SalesYTD della tabella SalesPerson in modo da includere le vendite più recenti registrate nella tabella SalesOrderHeader. La sottoquery aggrega le vendite per ogni venditore nell'istruzione 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. Aggiornamento di righe utilizzando i valori DEFAULT

Nell'esempio seguente viene impostata la colonna CostRate sul valore predefinito (0.00) per tutte le righe che contengono un valore CostRate maggiore di 20.00.

USE AdventureWorks;
GO
UPDATE Production.Location
SET CostRate = DEFAULT
WHERE CostRate > 20.00;

Specifica di oggetti di destinazione diversi dalle tabelle standard

Negli esempi di questa sezione viene illustrato come aggiornare le righe specificando una vista, un alias di tabella o una variabile di tabella.

A. Specifica di una vista come oggetto di destinazione

Nell'esempio seguente vengono aggiornate le righe di una tabella specificando una vista come oggetto di destinazione. Sebbene la definizione della vista faccia riferimento a più tabelle, l'istruzione UPDATE viene completata correttamente poiché fa riferimento a colonne presenti solo in una delle tabelle sottostanti. L'istruzione UPDATE non verrebbe eseguita correttamente se venissero specificate colonne da entrambe le tabelle. Per ulteriori informazioni, vedere Modifica di dati tramite una vista.

USE AdventureWorks;
GO
UPDATE Person.vStateProvinceCountryRegion
SET CountryRegionName = 'United States of America'
WHERE CountryRegionName = 'United States';

B. Specifica di un alias di tabella come oggetto di destinazione

Nell'esempio seguente vengono aggiornate le righe della tabella Production.ScrapReason. L'alias di tabella assegnato a ScrapReason nella clausola FROM viene specificato come oggetto di destinazione nella clausola UPDATE.

USE AdventureWorks;
GO
UPDATE sr
SET sr.Name += ' - tool malfunction'
FROM Production.ScrapReason AS sr
JOIN Production.WorkOrder AS wo 
     ON sr.ScrapReasonID = wo.ScrapReasonID
     AND wo.ScrappedQty > 300;

C. Specifica di una variabile di tabella come oggetto di destinazione

Nell'esempio seguente vengono aggiornate le righe in una variabile di tabella.

USE AdventureWorks;
GO
-- Create the table variable.
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    NewVacationHours int,
    ModifiedDate datetime);

-- Populate the table variable with employee ID values from HumanResources.Employee.
INSERT INTO @MyTableVar (EmpID)
    SELECT EmployeeID FROM HumanResources.Employee;

-- Update columns in the table variable.
UPDATE @MyTableVar
SET NewVacationHours = e.VacationHours + 20,
    ModifiedDate = GETDATE()
FROM HumanResources.Employee AS e 
WHERE e.EmployeeID = EmpID;

-- Display the results of the UPDATE statement.
SELECT EmpID, NewVacationHours, ModifiedDate FROM @MyTableVar
ORDER BY EmpID;
GO

Aggiornamento di dati basati su dati di altre tabelle

Negli esempi di questa sezione vengono illustrati i metodi per l'aggiornamento delle righe di una tabella in base alle informazioni presenti in un'altra tabella.

A. Utilizzo dell'istruzione UPDATE con informazioni di un'altra tabella

Nell'esempio seguente la colonna SalesYTD della tabella SalesPerson viene modificata in modo che includa le vendite più recenti registrate nella tabella 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

Nell'esempio precedente si presume che venga registrata una sola vendita per un determinato venditore in una data specifica e che i dati siano aggiornati. Se è possibile registrare più vendite per un determinato venditore nello stesso giorno, l'esempio non funziona correttamente. Viene eseguito senza errori, ma ogni valore SalesYTD viene aggiornato con una sola vendita, indipendentemente dal numero effettivo di vendite relative al giorno specificato. Un'istruzione UPDATE infatti non aggiorna mai la stessa riga due volte.

Nel caso in cui sia possibile registrare più vendite per un determinato venditore nello stesso giorno, tutte le vendite relative allo stesso venditore devono essere aggregate all'interno dell'istruzione UPDATE, come illustrato nell'esempio seguente:

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

Aggiornamento di righe in una tabella remota

Negli esempi di questa sezione viene illustrato come aggiornare le righe di una tabella di destinazione remota mediante un server collegato o una funzione per i set di righe per fare riferimento alla tabella remota.

A. Aggiornamento di dati in una tabella remota tramite un server collegato

Nell'esempio seguente viene aggiornata una tabella in un server remoto. L'esempio inizia con la creazione di un collegamento all'origine dati remota tramite sp_addlinkedserver. Il nome del server collegato, MyLinkServer, viene quindi specificato come parte del nome di oggetto in quattro parti nel formato server.catalogo.schema.oggetto. Si noti che è necessario specificare un nome del server valido per @datasrc.

USE master;
GO
-- Create a link to the remote data source. 
-- Specify a valid server name for @datasrc as 'server_name' or 'server_name\instance_name'.

EXEC sp_addlinkedserver @server = N'MyLinkServer',
    @srvproduct = N' ',
    @provider = N'SQLNCLI10', 
    @datasrc = N'<server name>',
    @catalog = N'AdventureWorks';
GO
USE AdventureWorks;
GO
-- Specify the remote data source using a four-part name 
-- in the form linked_server.catalog.schema.object.

UPDATE MyLinkServer.AdventureWorks.HumanResources.Department
SET GroupName = N'Public Relations'
WHERE DepartmentID = 4;

B. Aggiornamento di dati in una tabella remota tramite una funzione OPENQUERY

Nell'esempio seguente viene aggiornata una riga in una tabella remota specificando la funzione per i set di righe OPENQUERY. Viene utilizzato il nome del server collegato creato nell'esempio precedente.

UPDATE OPENQUERY (MyLinkServer, 'SELECT GroupName FROM HumanResources.Department WHERE DepartmentID = 4') 
SET GroupName = 'Sales and Marketing';

C. Aggiornamento di dati in una tabella remota tramite una funzione OPENDATASOURCE

Nell'esempio seguente viene inserita una riga in una tabella remota specificando la funzione per i set di righe OPENDATASOURCE. Specificare un nome server valido per l'origine dati utilizzando il formato nome_server oppure nome_server\nome_istanza. Potrebbe essere necessario configurare l'istanza di SQL Server per Ad Hoc Distributed Queries. Per ulteriori informazioni, vedere Opzione Ad Hoc Distributed Queries.

UPDATE OPENQUERY (MyLinkServer, 'SELECT GroupName FROM HumanResources.Department WHERE DepartmentID = 4') 
SET GroupName = 'Sales and Marketing';

Aggiornamento di tipi di dati LOB (Large Object)

Negli esempi di questa sezione vengono illustrati i metodi per l'aggiornamento dei valori nelle colonne definiti con tipi di dati LOB (Large Object).

A. Utilizzo di UPDATE con la clausola .WRITE per modificare i dati in una colonna nvarchar(max)

Nell'esempio seguente viene utilizzata la clausola .WRITE per aggiornare un valore parziale nella colonna DocumentSummary di tipo nvarchar(max) della tabella Production.Document . La parola components viene sostituita con la parola features specificando la parola sostitutiva, la posizione iniziale (offset) della parola da sostituire nei dati esistenti e il numero di caratteri da sostituire (lunghezza). Nell'esempio viene utilizzata anche la clausola OUTPUT per restituire le immagini pre-aggiornamento e post-aggiornamento della colonna DocumentSummary alla variabile di tabella @MyTableVar.

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

B. Utilizzo di UPDATE con la clausola .WRITE per aggiungere e rimuovere i dati in una colonna di tipo nvarchar(max)

Negli esempi seguenti vengono aggiunti e rimossi dati da una colonna di tipo nvarchar(max) che include un valore impostato su NULL. Poiché la clausola .WRITE non può essere utilizzata per modificare una colonna NULL, la colonna viene prima popolata con dati temporanei. Questi dati vengono quindi sostituiti con i dati corretti tramite la clausola .WRITE. Negli esempi aggiuntivi vengono accodati dati alla fine del valore della colonna, vengono rimossi (troncati) i dati dalla colonna e, infine, vengono rimossi i dati parziali dalla colonna. Le istruzioni SELECT visualizzano la modifica dei dati generata da ogni istruzione 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

C. Utilizzo di UPDATE con OPENROWSET per modificare una colonna di tipo varbinary(max)

Nell'esempio seguente un'immagine esistente archiviata in una colonna di tipo varbinary(max) viene sostituita con una nuova immagine. La funzione OPENROWSET viene utilizzata con l'opzione BULK per caricare l'immagine nella colonna. In questo esempio si presuppone che un file denominato Tires.jpg esista nel percorso di file specificato.

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

D. Utilizzo di UPDATE per modificare i dati FILESTREAM

Nell'esempio seguente viene utilizzata l'istruzione UPDATE per modificare i dati nel file del file system. Questo metodo non è consigliabile per trasmettere grandi quantità di dati in un file. Utilizzare le interfacce Win32 appropriate. Nell'esempio seguente viene sostituito il testo nel record del file con il testo Xray 1. Per ulteriori informazioni, vedere Panoramica di FILESTREAM.

UPDATE Archive.dbo.Records
SET [Chart] = CAST('Xray 1' as varbinary(max))
WHERE [SerialNumber] = 2;

Aggiornamento di tipi definiti dall'utente

Negli esempi seguenti vengono modificati i valori nelle colonne con tipo CLR definito dall'utente. Vengono illustrati tre metodi. Per ulteriori informazioni sulle colonne definite dall'utente, vedere Tipi CLR definiti dall'utente.

A. Utilizzo di un tipo di dati di sistema

È possibile aggiornare un tipo definito dall'utente specificando un valore in un tipo di dati di sistema SQL Server, a condizione che il tipo definito dall'utente supporti la conversione implicita o esplicita da tale tipo. Nell'esempio seguente viene illustrato come aggiornare un valore in una colonna del tipo Point definito dall'utente, eseguendo la conversione esplicita da una stringa.

UPDATE dbo.Cities
SET Location = CONVERT(Point, '12.3:46.2')
WHERE Name = 'Anchorage';

B. Chiamata di un metodo

È possibile aggiornare un tipo definito dall'utente richiamando un metodo, contrassegnato come mutatore, del tipo definito dall'utente per eseguire l'aggiornamento. Nell'esempio seguente viene richiamato un metodo mutatore di tipo Point denominato SetXY. In questo modo viene aggiornato lo stato dell'istanza del tipo.

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

C. Modifica del valore di una proprietà o di un membro dei dati

È possibile modificare un tipo definito dall'utente modificando il valore di una proprietà registrata o di un membro dei dati pubblici del tipo definito dall'utente. È necessario che l'espressione che fornisce il valore possa essere convertita in modo implicito nel tipo della proprietà. Nell'esempio seguente viene modificato il valore di proprietà X del tipo Point definito dall'utente.

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

Override del comportamento predefinito di Query Optimizer tramite hint

Negli esempi di questa sezione viene illustrato come utilizzare gli hint di tabella e gli hint per la query per eseguire temporaneamente l'override del comportamento predefinito di Query Optimizer durante l'elaborazione dell'istruzione UPDATE.

Nota di attenzioneAttenzione

Poiché Query Optimizer di SQL Server consente in genere di selezionare il piano di esecuzione migliore per una query, gli hint devono essere utilizzati da sviluppatori e amministratori di database esperti solo se strettamente necessario.

A. Specifica di un hint di tabella

Nell'esempio seguente viene specificato l'hint di tabella TABLOCK. Questo hint specifica l'acquisizione di un blocco condiviso sulla tabella Production.Product, che verrà mantenuto attivo fino al termine dell'istruzione UPDATE.

USE AdventureWorks;
GO
UPDATE Production.Product
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO

B. Specifica di un hint per la query

Nell'esempio seguente viene specificato l'hint per la queryOPTIMIZE FOR (@variable) nell'istruzione UPDATE. Questo hint indica a Query Optimizer di utilizzare un valore specifico per una variabile locale quando la query viene compilata e ottimizzata. Il valore viene utilizzato durante l'ottimizzazione della query e non durante la sua esecuzione.

USE AdventureWorks;
GO
CREATE PROCEDURE Production.uspProductUpdate
@Product nvarchar(25)
AS
SET NOCOUNT ON;
UPDATE Production.Product
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE @Product
OPTION (OPTIMIZE FOR (@Product = 'BK-%') );
GO
-- Execute the stored procedure 
EXEC Production.uspProductUpdate 'BK-%';

Acquisizione dei risultati dell'istruzione UPDATE

Negli esempi di questa sezione viene illustrato come utilizzare la clausola OUTPUT per restituire informazioni da ogni riga interessata da un'istruzione UPDATE o espressioni basate su di esse. Questi risultati possono essere restituiti all'applicazione di elaborazione per essere utilizzati in elementi quali messaggi di conferma, archiviazione e altri requisiti dell'applicazione simili.

A. Utilizzo di UPDATE con la clausola OUTPUT

Nell'esempio seguente viene aggiornata la colonna VacationHours nella tabella Employee del 25% per le prime 10 righe e viene inoltre impostato il valore nella colonna ModifiedDate sulla data corrente. La clausola OUTPUT restituisce il valore di VacationHours esistente prima di applicare l'istruzione UPDATE nella colonna deleted.VacationHours e il valore aggiornato nella colonna inserted.VacationHours alla variabile di tabella @MyTableVar.

Seguono due istruzioni SELECT che restituiscono i valori in @MyTableVar e i risultati dell'operazione di aggiornamento nella tabella Employee. Per ulteriori esempi sull'utilizzo della clausola OUTPUT, vedere Clausola 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,
    ModifiedDate = GETDATE() 
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.
SELECT TOP (10) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

Utilizzo di UPDATE in altre istruzioni

Negli esempi di questa sezione viene illustrato come utilizzare UPDATE in altre istruzioni.

A. Utilizzo di UPDATE in una stored procedure

Nell'esempio seguente viene utilizzata un'istruzione UPDATE in una stored procedure. La stored procedure richiede un parametro di input, @NewHours, e un parametro di output, @RowCount. Il valore del parametro @NewHours viene utilizzato nell'istruzione UPDATE per aggiornare la colonna VacationHours della tabella HumanResources.Employee. Il parametro di output @RowCount viene utilizzato per restituire il numero di righe interessate a una variabile locale. L'espressione CASE viene utilizzata nella clausola SET per determinare in modo condizionale il valore impostato per VacationHours. Quando un dipendente percepisce una paga oraria (SalariedFlag = 0), VacationHours viene impostato sul numero corrente di ore più il valore specificato in @NewHours. In caso contrario, VacationHours viene impostato sul valore specificato in @NewHours.

USE AdventureWorks;
GO
CREATE PROCEDURE HumanResources.Update_VacationHours
@NewHours smallint,
@RowCount int OUTPUT
AS 
SET NOCOUNT ON;
UPDATE HumanResources.Employee
SET VacationHours = 
    ( CASE
         WHEN SalariedFlag = 0 THEN VacationHours + @NewHours
         ELSE @NewHours
       END
    )
WHERE CurrentFlag = 1;
SET @RowCount = @@ROWCOUNT;
GO

-- Execute the stored procedure and return the number of rows updated to the variable @RowCount
DECLARE @RowCount int;
EXECUTE HumanResources.Update_VacationHours 40, @RowCount OUTPUT;
SELECT @RowCount AS RowCount;

B. Utilizzo di UPDATE in un blocco TRY…CATCH

Nell'esempio seguente viene utilizzata un'istruzione UPDATE in un blocco TRY…CATCH per gestire gli errori di esecuzione che possono verificarsi durante un'operazione di aggiornamento. Per ulteriori informazioni, vedere Utilizzo di TRY...CATCH in Transact-SQL.

USE AdventureWorks;
GO
BEGIN TRANSACTION;

BEGIN TRY
    -- Intentionally generate a constraint violation error.
    UPDATE HumanResources.Department
    SET Name = N'MyNewName'
    WHERE DepartmentID BETWEEN 1 AND 2;
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage;

    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO

Cronologia modifiche

Aggiornamento del contenuto

È stato aggiunto l'argomento table_alias alla sintassi come metodo per specificare la tabella di destinazione da aggiornare.

Sono state aggiunte informazioni nella sezione "Limitazioni e restrizioni" sull'utilizzo dell'espressione di tabella comune come destinazione di un'istruzione UPDATE.