UPDATE (Transact-SQL)
Modifica i dati esistenti in una tabella o vista in SQL Server 2012. Per alcuni esempi, vedere Esempi.
Convenzioni 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 di risultati di espressione di tabella comune è derivato da una query semplice e vi viene fatto riferimento dall'istruzione UPDATE.Le espressioni di tabella comune possono essere utilizzate anche con le istruzioni SELECT, INSERT, DELETE e CREATE VIEW. Per ulteriori informazioni, vedere WITH common_table_expression (Transact-SQL).
TOP ( expression**)** [ PERCENT ]
Specifica il numero o la percentuale di righe che verranno aggiornate. Il valore di expression può essere specificato come numero o come percentuale di righe.Le righe a cui viene fatto riferimento nell'espressione TOP utilizzata con INSERT, UPDATE o DELETE non sono ordinate.
Le parentesi che delimitano expression nell'espressione TOP sono obbligatorie nelle istruzioni INSERT, UPDATE 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 (che utilizza come nome un nome di server collegato o la funzione OPENDATASOURCE) in cui è contenuta la tabella o la vista. Se viene specificato server_name, sono necessari database_name e schema_name.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, in base alle funzionalità del provider.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
È una 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.
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
udt_column_name
Colonna definita dall'utente.property_name | field_name
Proprietà pubblica o membro pubblico di dati 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 è necessario modificare una sezione del valore di column_name . expression sostituisce le unità @Length che a partire da @Offset di column_name. Con questa clausola è possibile specificare solamente colonne varchar(max), nvarchar(max) o varbinary(max). column_name non può essere NULL e non può essere qualificato con un nome di tabella o un alias di tabella.expression è il valore copiato in column_name. expression deve restituire il tipo column_name o essere in grado di eseguire il cast implicito a tale tipo. 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 iniziale nel valore di column_name al quale è scritto expression. @Offset è una posizione ordinale in base zero, è bigint e non può essere un numero 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, sostituito da expression. @Length è 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 in cui è incluso 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 join applicate al risultato di una di tali chiamate non hanno effetto sui risultati dell'altra.
WHERE
Vengono specificate le condizioni che consentono di limitare 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.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.
GLOBAL
Specifica che 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 aggiornamenti.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
Utilizzare la funzione @@ROWCOUNT per restituire il numero di righe inserite nell'applicazione client. Per ulteriori informazioni, vedere @@ROWCOUNT (Transact-SQL).
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.
Prestare attenzione nello specificare la 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. Ad esempio, nell'istruzione UPDATE dello script riportato di seguito entrambe le righe in Table1 soddisfano le qualificazioni della clausola FROM nell'istruzione UPDATE, ma non viene specificato quale riga di Table1 viene utilizzata per aggiornare la riga in Table2.
USE AdventureWorks2012;
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 specificata la riga di Table2 da utilizzare per l'aggiornamento della riga in Table1.
USE AdventureWorks2012;
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
Supporto della compatibilità
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 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 di colonne text, ntext e image
Se si modifica una colonna 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 la colonna non venga aggiornata con NULL.
Per sostituire o modificare grandi blocchi di dati di tipo text, ntext o image, utilizzare le istruzioni WRITETEXT o UPDATETEXT invece dell'istruzione UPDATE.
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.
Importante |
---|
I tipi di dati ntext, text e image verranno rimossi in una versione futura 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. |
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. .Gli aggiornamenti WRITE che inseriscono o accodano nuovi dati vengono registrati in maniera minima se il modello di recupero del database è impostato sulla registrazione minima delle operazioni bulk oppure sulla registrazione minima. La registrazione minima non è utilizzata quando vengono aggiornati i valori esistenti. Per ulteriori informazioni, vedere Log delle transazioni (SQL Server).
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).
Per prestazioni ottimali, è consigliabile inserire o aggiornare i dati in dimensioni di blocco multiple di 8040 byte.
Se in una clausola OUTPUT si fa riferimento alla colonna modificata dalla clausola **.**WRITE, il valore completo della colonna, ovvero l'immagine precedente in **deleted.**column_name o l'immagine successiva in **inserted.**column_name,viene restituito nella colonna specificata nella variabile di tabella. Vedere l'esempio G seguente.
Per raggiungere la stessa funzionalità di **.**WRITE con altri tipi di dati character o binary, utilizzare STUFF (Transact-SQL).
Aggiornamento delle colonne di tipo definito dall'utente
L'aggiornamento dei valori nelle colonne di tipo definito dall'utente può essere eseguito in uno dei modi seguenti:
Specificando un valore in un tipo di dati di sistema SQL Server, a condizione che i tipi definiti dall'utente supportino la conversione implicita o esplicita da quel 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 Cities SET Location = CONVERT(Point, '12.3:46.2') WHERE Name = 'Anchorage';
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 Cities SET Location.SetXY(23.5, 23.5) WHERE Name = 'Anchorage';
[!NOTA]
SQL Server restituisce un errore se viene richiamato un metodo mutatore in un valore Null Transact-SQL oppure se un nuovo valore prodotto da un metodo mutatore è Null.
Modificando il valore di una proprietà registrata o di un membro pubblico di dati 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 di dati definito dall'utente Point.
UPDATE Cities SET Location.X = 23.5 WHERE Name = 'Anchorage';
Per modificare proprietà diverse della stessa colonna di tipo definito dall'utente, eseguire più istruzioni UPDATE o richiamare un metodo mutatore del tipo.
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 a dati FILESTREAM. Per ulteriori informazioni, vedere FILESTREAM (SQL Server).
Gestione degli errori
Se un'operazione di aggiornamento in una riga non rispetta un vincolo o una regola, viola l'impostazione 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. 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).
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).
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 e non corretti per specificare 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 blocco
Un'istruzione UPDATE acquisisce sempre un blocco esclusivo (X) sulla tabella che modifica e mantiene tale blocco fino al completamento della transazione. Con un blocco esclusivo, nessuna altra transazione può modificare dati. È possibile specificare hint di tabella per eseguire l'override di questo comportamento predefinito per la durata dell'istruzione UPDATE specificando un altro metodo di blocco. Gli hint dovrebbero comunque essere utilizzati solo se strettamente necessario ed esclusivamente da sviluppatori e amministratori di database esperti. Per ulteriori informazioni, vedere Hint di tabella (Transact-SQL).
Comportamento di registrazione
L'istruzione UPDATE viene registrata; tuttavia, per gli aggiornamenti parziali a tipi di dati per valori di grandi dimensioni tramite la clausola **.**WRITE viene eseguita una registrazione minima. Per ulteriori informazioni, vedere "Aggiornamento dei tipi di dati per valori di grandi dimensioni" nella sezione precedente "Tipi di dati".
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 per l'istruzione UPDATE vengono assegnate per impostazione predefinita ai membri del ruolo predefinito del server sysadmin, 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 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 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 contenuti in questa sezione vengono illustrate le funzionalità di base dell'istruzione UPDATE tramite la sintassi minima richiesta.
A.Esecuzione di un'istruzione UPDATE semplice
Nell'esempio seguente viene aggiornata una singola colonna per tutte le righe della tabella Person.Address.
USE AdventureWorks2012;
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 AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL;
GO
Limitazione delle righe aggiornate
Negli esempi contenuti in questa sezione vengono illustrati i modi 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 AdventureWorks2012;
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 AdventureWorks2012;
GO
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 ;
GO
Se è necessario utilizzare TOP per applicare gli aggiornamenti in un ordine cronologico significativo, è necessario utilizzare TOP 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 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 di parti utilizzate per compilare tali componenti e così via. Vengono modificate solo le righe restituite dall'espressione di tabella comune.
USE AdventureWorks2012;
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 AdventureWorks2012;
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 valori calcolati in un'istruzione UPDATE. Nell'esempio viene raddoppiato il valore della colonna ListPrice per tutte le righe della tabella Product.
USE AdventureWorks2012 ;
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 AdventureWorks2012;
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 AdventureWorks2012;
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 AdventureWorks2012;
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 AdventureWorks2012;
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 esito negativo se venissero specificate colonne di entrambe le tabelle. Per ulteriori informazioni, vedere Modificare i dati tramite una vista.
USE AdventureWorks2012;
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 AdventureWorks2012;
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 AdventureWorks2012;
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 AdventureWorks2012;
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 AdventureWorks2012;
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 quindi specificato come parte del nome di oggetto in quattro parti nel formato server.catalogo.schema.oggetto. 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'AdventureWorks2012';
GO
USE AdventureWorks2012;
GO
-- Specify the remote data source using a four-part name
-- in the form linked_server.catalog.schema.object.
UPDATE MyLinkServer.AdventureWorks2012.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 di configurazione del server 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, il percorso iniziale (offset) della parola da sostituire nei dati esistenti e il numero di caratteri da sostituire (lunghezza). Nell'esempio viene inoltre utilizzata la clausola OUTPUT per restituire le immagini precedente e successiva della colonna DocumentSummary nella variabile di tabella @MyTableVar.
USE AdventureWorks2012;
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 al termine del valore della colonna, rimossi (troncati) dati dalla colonna e infine rimossi dati parziali dalla colonna. Le istruzioni SELECT consentono di visualizzare la modifica dei dati generata da ogni istruzione UPDATE.
USE AdventureWorks2012;
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 AdventureWorks2012;
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 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 appropriate. Nell'esempio seguente viene sostituito il testo nel record del file con il testo Xray 1. Per ulteriori informazioni, vedere FILESTREAM (SQL Server).
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 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 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 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. 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 di proprietà X del tipo definito dall'utente Point.
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.
Attenzione |
---|
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 ed esclusivamente da sviluppatori e amministratori di database esperti. |
A.Specifica di 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 AdventureWorks2012;
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 query OPTIMIZE FOR (@variable) nell'istruzione UPDATE. Tramite questo hint si 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 AdventureWorks2012;
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 INSERT. Questi risultati possono essere restituiti all'applicazione di elaborazione per l'utilizzo in messaggi di errore, attività di archiviazione e altre operazioni simili dell'applicazione.
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 AdventureWorks2012;
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 retribuzione 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 AdventureWorks2012;
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.
USE AdventureWorks2012;
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
Vedere anche
Riferimento
Funzioni per i valori text e image (Transact-SQL)
WITH common_table_expression (Transact-SQL)