Modifica di dati tramite una vista
È possibile modificare i dati di una tabella di base sottostante tramite una vista, nello stesso modo in cui si modificano i dati di una tabella, utilizzando istruzioni UPDATE, INSERT e DELETE oppure l'utilità bcp e l'istruzione BULK INSERT. Le limitazioni seguenti, tuttavia, riguardano solo l'aggiornamento delle viste e non si applicano alle tabelle:
[!NOTA]
Alcune delle restrizioni seguenti non riguardano le viste partizionate e nessuna di tali restrizioni riguarda gli aggiornamenti eseguiti tramite trigger INSTEAD OF. Per ulteriori informazioni, vedere "Altre opzioni per la modifica di dati tramite una vista" di seguito in questo argomento.
Tutte le modifiche, incluse le istruzioni UPDATE, INSERT e DELETE, devono fare riferimento a colonne di una sola tabella di base.
Le colonne che vengono modificate nella vista devono fare riferimento direttamente ai dati sottostanti nelle colonne della tabella. Non possono essere derivate in altro modo, ad esempio tramite:
Una funzione di aggregazione, ovvero AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV, STDEVP, VAR e VARP.
Un calcolo. Non è possibile calcolare la colonna in base a un'espressione che utilizza altre colonne. Le colonne formate utilizzando operatori sugli insiemi, ovvero UNION, UNION ALL, CROSSJOIN, EXCEPT e INTERSECT, equivalgono a un calcolo e non sono pertanto aggiornabili.
Le colonne che vengono modificate non possono essere interessate da clausole GROUP BY, HAVING o DISTINCT.
Non è possibile utilizzare la clausola TOP nell'istruzione select_statement della vista quando si utilizza anche WITH CHECK OPTION.
Le restrizioni sopra indicate sono valide sia per qualsiasi sottoquery nella clausola FROM della vista sia per la vista stessa. In generale, in SQL Server 2008 deve essere possibile tracciare in modo non ambiguo le modifiche dalla definizione della vista a una tabella di base. La vista seguente, ad esempio, non è aggiornabile:
CREATE VIEW TotalSalesContacts
AS
SELECT C.LastName,
SUM(O.TotalDue) AS TotalSales
FROM Sales.SalesOrderHeader O, Person.Contact C
WHERE C.ContactID = O.ContactID
GROUP BY LastName
Una modifica apportata alla colonna LastName di TotalSalesContacts non sarebbe accettabile in quanto la colonna è stata interessata da una clausola GROUP BY. Se vi sono più istanze dello stesso cognome, non sarà possibile stabilire quale aggiornare, inserire o eliminare. Analogamente, un tentativo di modificare la colonna TotalSales di TotalSalesContacts restituirebbe un errore, in quanto si tratta di una colonna derivata da una funzione di aggregazione. In SQL Server non è possibile tracciare questa colonna direttamente alla relativa tabella di base SalesOrderHeader.
Valgono inoltre le seguenti linee guida aggiuntive:
Se la clausola WITH CHECK OPTION viene utilizzata nella definizione della vista, tutte le istruzioni di modifica dei dati eseguite nella vista devono essere conformi ai criteri impostati nell'istruzione SELECT che definisce la vista. Se si utilizza la clausola WITH CHECK OPTION, non è possibile modificare le righe in modo che scompaiano dalla vista. Eventuali modifiche di questo tipo verranno annullate e verrà generato un errore.
Nelle istruzioni INSERT devono essere specificati i valori per le colonne della tabella sottostante che non consentono valori Null e non dispongono di definizioni DEFAULT.
I dati modificati nelle colonne della tabella sottostante devono essere conformi alle restrizioni di tali colonne, ad esempio supporto di valori Null, vincoli, definizioni DEFAULT e così via. Se, ad esempio, si elimina una riga, tutti i vincoli FOREIGN KEY sottostanti nelle tabelle correlate devono essere soddisfatti per eseguire correttamente l'eliminazione.
Non è possibile aggiornare una vista partizionata distribuita, ovvero una vista remota, utilizzando un cursore gestito da keyset. Questa restrizione può essere risolta dichiarando il cursore nelle tabelle sottostanti e non nella vista stessa.
L'importazione bulk di dati in una vista partizionata non è supportata da bcp o dalle istruzioni BULK INSERT e INSERT ... SELECT * FROM OPENROWSET(BULK...). È tuttavia possibile inserire più righe in una vista partizionata utilizzando l'istruzione INSERT. Per ulteriori informazioni, vedere Esportazione o importazione bulk di dati da o in una vista.
Non è possibile utilizzare le istruzioni READTEXT and WRITETEXT con le colonne text, ntext e image in una vista.
Altre opzioni per la modifica di dati tramite una vista
Se le restrizioni sopra indicate non consentono di modificare i dati direttamente tramite una vista, è possibile ricorrere alle soluzioni seguenti:
Utilizzare trigger INSTEAD OF con la logica per supportare le istruzioni INSERT, UPDATE e DELETE. Per ulteriori informazioni, vedere Progettazione di trigger INSTEAD OF.
Utilizzare viste partizionate aggiornabili che consentano di modificare una o più tabelle membro. Per ulteriori informazioni, vedere Creazione di viste partizionate.
Per aggiungere dati tramite una vista
Per modificare dati tramite una vista
Per eliminare dati tramite una vista