UPDATE (Transact-SQL)

Modifica dati esistenti in una o più colonne in una tabella o vista in SQL Server 2008 R2. Per alcuni esempi, vedere Esempi.

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 { += | -= | *= | /= | %= | &= | ^= | |= } 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, anche noto come espressione di tabella comune (CTE), definito nell'ambito di un'istruzione SELECT, INSERT, UPDATE o DELETE. Il set dei risultati dell'espressione di tabella comune deriva da una query semplice 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 sia un numero sia una percentuale di righe.

    Le righe cui viene fatto riferimento nell'espressione TOP utilizzata con 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 di server collegato o tramite 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 e non essere soggetti alle funzionalità del provider OLE DB che accede 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 devono essere aggiornate le righe. È necessario che la vista cui si fa riferimento in table_or_view_name sia aggiornabile e includa un riferimento esatto a un'unica tabella di base nella clausola FROM 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 una tabella di destinazione. La parola chiave WITH e le parentesi sono obbligatorie. 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 carattere Unicode nchar, nvarchar e ntext, "expression" deve essere preceduto dalla lettera maiuscola "N". Se la lettera "N" viene omessa, 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.

  • 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 di assegnazione composto:

    += Aggiunta e assegnazione

    -= Sottrazione e assegnazione

    *= Moltiplicazione e assegnazione

    /= Divisione e assegnazione

    %= Applicazione del coefficiente 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 dati pubblico di un tipo definito dall'utente.

  • method_name(argument [ ,... n] )
    Metodo mutatore pubblico non static di udt_column_name che accetta uno o più argomenti.

  • **.**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 al termine del valore column_name.

    Per ulteriori informazioni, vedere la sezione Osservazioni.

  • @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 in alcuna istruzione DML applicata a 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 un alias dell'oggetto.

    Una vista che include un trigger INSTEAD OF UPDATE non può essere la destinazione di un'istruzione UPDATE in cui è specificata la clausola FROM.

    Nota

    Qualsiasi chiamata a OPENDATASOURCE, OPENQUERY o OPENROWSET nella clausola FROM viene valutata separatamente e indipendentemente da qualsiasi altra chiamata a queste funzioni utilizzate come destinazione dell'aggiornamento, anche se alle due chiamate vengono forniti argomenti identici. In particolare, le condizioni di filtro o di join applicate al risultato di una di tali chiamate non avranno alcun effetto sui risultati dell'altra chiamata.

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

  • <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
    Specifica 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 che un cursore locale denominati cursor_name, questo argomento indica il cursore globale se è stato specificato l'argomento GLOBAL. In caso contrario, indica il 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 ] )
    Indica 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 AdventureWorks2008R2;
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), (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 quale riga di Table2 deve essere utilizzata per l'aggiornamento della riga nella tabella Table1.

USE AdventureWorks2008R2;
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

Informazioni sulla compatibilità

SET ROWCOUNT non avrà effetto sulle istruzioni DELETE, INSERT e UPDATE in una versione futura di SQL Server. Non utilizzare SET ROWCOUNT con le istruzioni DELETE, INSERT e UPDATE in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni in cui è attualmente implementata. È consigliabile utilizzare la sintassi TOP.

In una versione futura di SQL Server verrà rimosso il supporto per l'utilizzo degli hint READUNCOMMITTED e NOLOCK nella clausola FROM per la tabella di destinazione di un'istruzione UPDATE o DELETE. Evitare di utilizzare questi hint in questo contesto nei nuovi progetti di sviluppo e pianificare la modifica delle applicazioni in cui sono attualmente utilizzati.

Tipi di dati

Tutte le colonne di tipo char e nchar vengono riempite con spazi 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 da una delle prossime versioni di Microsoft SQL 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 non rispetta un vincolo o una regola, viene violata 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.

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.

Sicurezza

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 aggiornate

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

Impostazione dei 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 in base ai dati di altre tabelle

FROM

Aggiornamento di righe in una tabella remota

server collegato • OPENQUERY • OPENDATASOURCE

Aggiornamento di tipi di dati per oggetti di grandi dimensioni

.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 le query

Acquisizione dei risultati dell'istruzione UPDATE

Clausola OUTPUT

Utilizzo di UPDATE in altre istruzioni

Stored procedure • TRY…CATCH

Sintassi di base

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

A. Esecuzione di un'istruzione UPDATE semplice

Nell'esempio seguente viene aggiornata una singola colonna per tutte le righe della tabella Person.Address.

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

B. Aggiornamento di più colonne

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

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

Limitazione delle righe aggiornate

Negli esempi contenuti in questa sezione vengono illustrate le modalità che è possibile 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 un valore "Red" esistente nella colonna Color e un valore nella colonna Name che inizia con "Road-250".

USE AdventureWorks2008R2;
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 AdventureWorks2008R2;
GO
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 ;
GO

Se si desidera utilizzare TOP per applicare gli aggiornamenti in un ordine cronologico significativo, è necessario utilizzare TOP insieme a ORDER BY in un'istruzione di selezione secondaria. 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 BusinessEntityID FROM HumanResources.Employee
     ORDER BY HireDate ASC) AS th
WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID;
GO

C. Utilizzo della clausola WITH common_table_expression

Nell'esempio seguente viene aggiornato il valore PerAssemnblyQty per tutte le parti e tutti i componenti utilizzati direttamente o indirettamente per creare ProductAssemblyID 800. L'espressione di tabella comune restituisce un elenco gerarchico di parti utilizzate direttamente per compilare ProductAssemblyID 800 e parti utilizzate per compilare tali componenti e così via. Vengono modificate solo le righe restituite dall'espressione di tabella comune. Per ulteriori informazioni sulle espressioni di tabella comune ricorsive, vedere Query ricorsive tramite espressioni di tabella comuni.

USE AdventureWorks2008R2;
GO
WITH Parts(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) AS
(
    SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty,
        b.EndDate, 0 AS ComponentLevel
    FROM Production.BillOfMaterials AS b
    WHERE b.ProductAssemblyID = 800
          AND b.EndDate IS NULL
    UNION ALL
    SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty,
        bom.EndDate, ComponentLevel + 1
    FROM Production.BillOfMaterials AS bom 
        INNER JOIN Parts AS p
        ON bom.ProductAssemblyID = p.ComponentID
        AND bom.EndDate IS NULL
)
UPDATE Production.BillOfMaterials
SET PerAssemblyQty = c.PerAssemblyQty * 2
FROM Production.BillOfMaterials AS c
JOIN Parts AS d ON c.ProductAssemblyID = d.AssemblyID
WHERE d.ComponentLevel = 0; 

D. Utilizzo della clausola WHERE CURRENT OF

Nell'esempio seguente viene utilizzata la clausola WHERE CURRENT OF per aggiornare solo la riga in 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 AdventureWorks2008R2;
GO
DECLARE complex_cursor CURSOR FOR
    SELECT a.BusinessEntityID
    FROM HumanResources.EmployeePayHistory AS a
    WHERE RateChangeDate <> 
         (SELECT MAX(RateChangeDate)
          FROM HumanResources.EmployeePayHistory AS b
          WHERE a.BusinessEntityID = b.BusinessEntityID) ;
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 dei valori di colonna

Negli esempi contenuti in questa sezione viene illustrato l'aggiornamento di colonne tramite valori calcolati, sottoquery e valori DEFAULT.

A. Specifica di un valore calcolato

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

USE AdventureWorks2008R2 ;
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 AdventureWorks2008R2;
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 con ScrapReasonID tra 10 e 12.

USE AdventureWorks2008R2;
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 la colonna SalesYTD della tabella SalesPerson viene modificata in modo che includa le vendite più recenti registrate nella tabella SalesOrderHeader. La sottoquery aggrega le vendite per ogni venditore nell'istruzione UPDATE.

USE AdventureWorks2008R2;
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.BusinessEntityID = so.SalesPersonID
     GROUP BY so.SalesPersonID);
GO

D. Aggiornamento di righe tramite valori DEFAULT

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

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

Specifica di oggetti di destinazione diversi dalle tabelle standard

Negli esempi contenuti in 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. La definizione di vista fa riferimento a più tabelle, tuttavia, l'istruzione UPDATE ha esito positivo perché fa riferimento alle colonne di una sola delle tabelle sottostanti. L'istruzione UPDATE avrebbe avuto esito negativo se fossero state specificate colonne di entrambe le tabelle. Per ulteriori informazioni, vedere Modifica di dati tramite una vista.

USE AdventureWorks2008R2;
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 nella tabella Production.ScrapReason. L'alias di tabella assegnato a ScrapReason nella clausola FROM viene specificato come oggetto di destinazione nella clausola UPDATE.

USE AdventureWorks2008R2;
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 AdventureWorks2008R2;
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 BusinessEntityID 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.BusinessEntityID = EmpID;

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

Aggiornamento di dati in base ai dati di altre tabelle

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

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 AdventureWorks2008R2;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + SubTotal
FROM Sales.SalesPerson AS sp
JOIN Sales.SalesOrderHeader AS so
    ON sp.BusinessEntityID = so.SalesPersonID
    AND so.OrderDate = (SELECT MAX(OrderDate)
                        FROM Sales.SalesOrderHeader
                        WHERE SalesPersonID = sp.BusinessEntityID);
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 AdventureWorks2008R2;
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.BusinessEntityID = 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 in una tabella di destinazione remota tramite 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 successivamente specificato come parte del nome di oggetto in quattro parti nel formato server.catalog.schema.object. Si noti che è necessario specificare un nome 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'AdventureWorks2008R2';
GO
USE AdventureWorks2008R2;
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 di server valido per l'origine dati utilizzando il formato server_name o server_name\instance_name. 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 per oggetti di grandi dimensioni

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

A. Utilizzo di UPDATE con la clausola .WRITE per modificare 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 per restituire le immagini pre-aggiornamento e post-aggiornamento della colonna DocumentSummary alla variabile di tabella @MyTableVar.

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table (
    SummaryBefore nvarchar(max),
    SummaryAfter nvarchar(max));
UPDATE Production.Document
SET DocumentSummary .WRITE (N'features',28,10)
OUTPUT deleted.DocumentSummary, 
       inserted.DocumentSummary 
    INTO @MyTableVar
WHERE Title = N'Front Reflector Bracket Installation';
SELECT SummaryBefore, SummaryAfter 
FROM @MyTableVar;
GO

B. Utilizzo di UPDATE con la clausola .WRITE per aggiungere e rimuovere 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, rimossi (troncati) dati dalla colonna e, infine, rimossi dati parziali dalla colonna. Le istruzioni SELECT visualizzano la modifica dei dati generata da ogni istruzione UPDATE.

USE AdventureWorks2008R2;
GO
-- Replacing NULL value with temporary data.
UPDATE Production.Document
SET DocumentSummary = N'Replacing NULL value'
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
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 Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
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 Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
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 Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
-- Removing partial data beginning at position 9 and ending at 
-- position 21.
UPDATE Production.Document
SET DocumentSummary .WRITE ('',9, 12)
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
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 Tires.jpg esista nel percorso di file specificato.

USE AdventureWorks2008R2;
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 tramite flusso grandi quantità di dati in un file. Utilizzare le interfacce Win32 adatte. 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 di tipo CLR definite 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 di 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 di 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 dati

È possibile aggiornare un tipo definito dall'utente modificando il valore di una proprietà registrata o di un membro dati pubblico 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 della proprietà X del tipo di dati 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 contenuti in questa sezione viene illustrato come utilizzare gli hint di tabella e gli hint per le 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 solo se strettamente necessario da sviluppatori e amministratori di database esperti.

A. Specifica un hint di tabella

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

USE AdventureWorks2008R2;
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 l'esecuzione.

USE AdventureWorks2008R2;
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 contenuti in questa sezione viene illustrato come utilizzare la clausola OUTPUT per restituire informazioni da (o espressioni basate su) ogni riga interessata da un'istruzione UPDATE. Questi risultati possono essere restituiti all'applicazione di elaborazione per l'utilizzo in messaggi di conferma, archiviazione e altri scopi 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 AdventureWorks2008R2;
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.BusinessEntityID,
       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) BusinessEntityID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

Utilizzo di UPDATE in altre istruzioni

Negli esempi inclusi in questa sezione viene illustrato l'utilizzo di UPDATE in altre istruzioni.

A. Utilizzo di UPDATE in una stored procedure

Nell'esempio seguente viene utilizzata un'istruzione UPDATE in una stored procedure. Per la stored procedure è previsto un unico parametro di input @NewHours e un unico 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 nella stored procedure @NewHours. In caso contrario, VacationHours viene impostato sul valore specificato in @NewHours.

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

EXEC HumanResources.Update_VacationHours 40;

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 potrebbero verificarsi durante un'operazione di aggiornamento. Per ulteriori informazioni, vedere Utilizzo di TRY...CATCH in Transact-SQL.

USE AdventureWorks2008R2;
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