UPDATE (Transact-SQL)

Modifica i dati esistenti in una tabella o in una vista.

Icona di collegamento a un argomentoConvenzioni della sintassi Transact-SQL

Sintassi

[ WITH <common_table_expression> [...n] ]
UPDATE 
    [ TOP ( expression ) [ PERCENT ] ] 
    { <object> | rowset_function_limited 
     [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
    }
    SET 
        { column_name = { expression | DEFAULT | NULL }
          | { udt_column_name.{ { property_name = expression 
                                | field_name = expression } 
                               | method_name ( argument [ ,...n ] ) 
                              } 
            }
          | column_name { .WRITE ( expression , @Offset , @Length ) }
          | @variable = expression 
          | @variable = column = expression [ ,...n ] 
        } [ ,...n ] 
    [ <OUTPUT Clause> ]
    [ FROM{ <table_source> } [ ,...n ] ] 
    [ WHERE { <search_condition> 
            | { [ CURRENT OF 
                  { { [ GLOBAL ] cursor_name } 
                      | cursor_variable_name 
                  } 
                ]
              }
            } 
    ] 
    [ OPTION ( <query_hint> [ ,...n ] ) ]
[ ; ]

<object> ::=
{ 
    [ server_name . database_name . schema_name . 
    | database_name .[ schema_name ] . 
    | schema_name .
    ]
        table_or_view_name}

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 ELECT, 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. expression può essere un numero o una percentuale delle 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 necessarie nelle istruzioni INSERT, UPDATE e DELETE. Per ulteriori informazioni, vedere TOP (Transact-SQL).

  • 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 si desidera aggiornare le righe.

    Per l'origine di tabella in un'istruzione DELETE è possibile utilizzare una variabile table nel proprio ambito di validità.

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

  • 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 table_hint (Transact-SQL).
  • SET
    Specifica 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.
  • 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 supporta valori Null.
  • 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 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, Microsoft Motore di database di SQL Server 2005 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.

  • 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 ] )
    Specifica che vengono utilizzati hint per l'ottimizzazione per personalizzare la modalità di elaborazione dell'istruzione in Motore di database. Per ulteriori informazioni, vedere query_hint (Transact-SQL).

Osservazioni

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 la sezione "Aggiornamento dei tipi di dati per valori di grandi dimensioni", riportata di seguito.

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

Se un'operazione di aggiornamento non rispetta un vincolo o una regola, viola l'impostazione relativa al supporto dei valori Null per la colonna oppure il tipo di dati del nuovo valore è un tipo 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 un aggiornamento a una o più colonne che fanno parte di un indice cluster provoca l'aumento delle dimensioni dell'indice cluster fino a superare 8.060 byte, l'aggiornamento non viene eseguito correttamente e viene restituito un messaggio di errore.

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.

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

L'impostazione dell'opzione SET ROWCOUNT viene ignorata per le istruzioni UPDATE eseguite su tabelle remote e viste partizionate locali e remote.

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

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.

Utilizzo di UPDATE con la clausola FROM

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 della tabella Table1 soddisfano le condizioni della clausola FROM nell'istruzione UPDATE, ma non viene specificato quale riga di Table1 viene utilizzata per aggiornare la riga nella tabella Table2..

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
    DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
    DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1 
    (ColA int NOT NULL, ColB decimal(10,3) NOT NULL);
GO
CREATE TABLE dbo.Table2 
    (ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES(1, 10.0);
INSERT INTO dbo.Table1 VALUES(1, 20.0);
INSERT INTO dbo.Table2 VALUES(1, 0.0);
GO
UPDATE dbo.Table2 
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
FROM dbo.Table2 
    INNER JOIN dbo.Table1 
    ON (dbo.Table2.ColA = dbo.Table1.ColA);
GO
SELECT ColA, ColB 
FROM dbo.Table2;

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

USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
    DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
    DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1
    (c1 int PRIMARY KEY NOT NULL, c2 int NOT NULL);
GO
CREATE TABLE dbo.Table2
    (d1 int PRIMARY KEY NOT NULL, d2 int NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES (1, 10);
INSERT INTO dbo.Table2 VALUES (1, 20);
INSERT INTO dbo.Table2 VALUES (2, 30);
GO
DECLARE abc CURSOR LOCAL FOR
    SELECT c1, c2 
    FROM dbo.Table1;
OPEN abc;
FETCH abc;
UPDATE dbo.Table1 
SET c2 = c2 + d2 
FROM dbo.Table2 
WHERE CURRENT OF abc;
GO
SELECT c1, c2 FROM dbo.Table1;
GO

Aggiornamento delle colonne definite dall'utente

L'aggiornamento dei valori nelle tabelle definite dall'utente può essere eseguito utilizzando una delle opzioni descritte di seguito:

  • 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 vengono modificati i valori delle proprietà X del tipo di dati Point definito dall'utente.

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

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

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 su registrazione minima delle transazioni di massa oppure su registrazione minima. La registrazione minima non è utilizzata quando vengono aggiornati i valori esistenti. Per ulteriori informazioni, vedere Operazioni con registrazione minima.

In Motore di database di SQL Server 2005 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 pre-aggiornamento in **deleted.**column_name oppure l'immagine post-aggiornamento in **inserted.**column_name, viene restituito nella colonna specificata nella variabile della 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 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, vi viene associato un puntatore di testo valido e vi viene allocata almeno una pagina di dati, a meno che non si esegua l'aggiornamento della colonna con NULL.

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

ms177523.note(it-it,SQL.90).gifImportante:
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.

Utilizzo di trigger INSTEAD OF su azioni UPDATE

Quando viene definito un trigger INSTEAD OF in operazioni 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).

Impostazione di variabili e colonne

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.

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 le autorizzazioni ad altri utenti.

Esempi

A. Esecuzione di un'istruzione UPDATE semplice

Negli esempi seguenti viene illustrato come tutte le righe possono essere interessate quando una clausola WHERE non viene utilizzata per specificare la riga o le righe da aggiornare.

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

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

In un'istruzione UPDATE è inoltre possibile utilizzare valori calcolati. Nell'esempio seguente viene raddoppiato il valore della colonna ListPrice per tutte le righe della tabella Product.

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

B. Utilizzo dell'istruzione UPDATE con una clausola WHERE

Nell'esempio seguente viene utilizzata la clausola WHERE per specificare le righe da aggiornare. Ad esempio, Adventure Works Cycles vende il modello di bicicletta Road-250 in due colori: rosso e nero. La società ha deciso di cambiare il colore di questo modello da rosso a rosso metallizzato. Nell'istruzione seguente vengono aggiornate le righe nella tabella Production.Product per tutti i prodotti Road-250 rossi.

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

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

Nell'esempio seguente la colonna SalesYTD della tabella SalesPerson viene modificata in modo che includa le vendite più recenti registrate nella tabella SalesOrderHeader.

USE AdventureWorks;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + SubTotal
FROM Sales.SalesPerson AS sp
JOIN Sales.SalesOrderHeader AS so
    ON sp.SalesPersonID = so.SalesPersonID
    AND so.OrderDate = (SELECT MAX(OrderDate)
                        FROM Sales.SalesOrderHeader 
                        WHERE SalesPersonID = 
                              sp.SalesPersonID);
GO

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

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

USE AdventureWorks;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + 
    (SELECT SUM(so.SubTotal) 
     FROM Sales.SalesOrderHeader AS so
     WHERE so.OrderDate = (SELECT MAX(OrderDate)
                           FROM Sales.SalesOrderHeader AS so2
                           WHERE so2.SalesPersonID = 
                                 so.SalesPersonID)
     AND Sales.SalesPerson.SalesPersonID = so.SalesPersonID
     GROUP BY so.SalesPersonID);
GO

D. Utilizzo di UPDATE con la clausola TOP

Nell'esempio seguente viene aggiornata la colonna VacationHours del 25% per 10 righe casuali nella tabella Employee.

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

E. 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. 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@MyTableVartable.

Seguono due istruzioni SELECT che restituiscono i valori in @MyTableVar e i risultati dell'operazione di aggiornamento nella tabella Employee. Si noti che i risultati nella colonna INSERTED.ModifiedDate sono diversi dai valori nella colonna ModifiedDate della tabella Employee . Questo perché il trigger AFTER UPDATE che aggiorna il valore di ModifiedDate alla data corrente è definito nella tabella Employee. Le colonne restituite da OUTPUT, tuttavia, riflettono i dati prima dell'attivazione dei trigger. Per ulteriori esempi sull'utilizzo della clausola OUTPUT, vedere Clausola OUTPUT (Transact-SQL).

USE AdventureWorks;
GO
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    OldVacationHours int,
    NewVacationHours int,
    ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 
OUTPUT INSERTED.EmployeeID,
       DELETED.VacationHours,
       INSERTED.VacationHours,
       INSERTED.ModifiedDate
INTO @MyTableVar;
--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO
--Display the result set of the table.
--Note that ModifiedDate reflects the value generated by an
--AFTER UPDATE trigger.
SELECT TOP (10) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

F. Utilizzo di UPDATE con la clausola WITH common_table_expression

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

USE AdventureWorks;
GO
WITH DirectReports(EmployeeID, NewVacationHours, EmployeeLevel)
AS
(SELECT e.EmployeeID, e.VacationHours, 1
  FROM HumanResources.Employee AS e
  WHERE e.ManagerID = 12
  UNION ALL
  SELECT e.EmployeeID, e.VacationHours, EmployeeLevel + 1
  FROM HumanResources.Employee as e
  JOIN DirectReports AS d ON e.ManagerID = d.EmployeeID
)
UPDATE HumanResources.Employee
SET VacationHours = VacationHours * 1.25
FROM HumanResources.Employee AS e
JOIN DirectReports AS d ON e.EmployeeID = d.EmployeeID;
GO

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

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

USE AdventureWorks;
GO
DECLARE @MyTableVar table (
    DocumentID int NOT NULL,
    SummaryBefore nvarchar(max),
    SummaryAfter nvarchar(max));
UPDATE Production.Document
SET DocumentSummary .WRITE (N'features',28,10)
OUTPUT INSERTED.DocumentID,
       DELETED.DocumentSummary, 
       INSERTED.DocumentSummary 
    INTO @MyTableVar
WHERE DocumentID = 3 ;
SELECT DocumentID, SummaryBefore, SummaryAfter 
FROM @MyTableVar;
GO

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

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

USE AdventureWorks;
GO
-- Replacing NULL value with temporary data.
UPDATE Production.Document
SET DocumentSummary = N'Replacing NULL value'
WHERE DocumentID = 1;
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO
-- Replacing temporary data with the correct data. Setting @Length to NULL 
-- truncates all existing data from the @Offset position.
UPDATE Production.Document
SET DocumentSummary .WRITE(N'Carefully inspect and maintain the tires and crank arms.',0,NULL)
WHERE DocumentID = 1;
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO
-- Appending additional data to the end of the column by setting 
-- @Offset to NULL.
UPDATE Production.Document
SET DocumentSummary .WRITE (N' Appending data to the end of the column.', NULL, 0)
WHERE DocumentID = 1;
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO
-- Removing all data from @Offset to the end of the existing value by 
-- setting expression to NULL. 
UPDATE Production.Document
SET DocumentSummary .WRITE (NULL, 56, 0)
WHERE DocumentID = 1;
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO
-- Removing partial data beginning at position 9 and ending at 
-- position 21.
UPDATE Production.Document
SET DocumentSummary .WRITE ('',9, 12)
WHERE DocumentID = 1;
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE DocumentID = 1;
GO

I. 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 AdventureWorks;
GO
UPDATE Production.ProductPhoto
SET ThumbNailPhoto = (
    SELECT *
    FROM OPENROWSET(BULK 'c:\Tires.jpg', SINGLE_BLOB)AS x )
WHERE ProductPhotoID = 1;
GO

Vedere anche

Riferimento

CREATE TABLE (Transact-SQL)
CREATE TRIGGER (Transact-SQL)
Cursori (Transact-SQL)
DELETE (Transact-SQL)
INSERT (Transact-SQL)
OPENROWSET (Transact-SQL)
Funzioni per i valori text e image (Transact-SQL)
WITH common_table_expression (Transact-SQL)

Altre risorse

Aggiornamento dei dati in una tabella

Guida in linea e informazioni

Assistenza su SQL Server 2005