xplayn > share your experience     
RSS Feed Login     Password        » Registrati «
  
          Home
  Team & Mission
          News
  Development
  Database
          Pubblicazioni
  Articoli
  Tips
  IMHO
          Risorse
  Guide/Manuali/Tools
  Glossario SQLServer
  Collabora con noi
          Blogs
  Maurizio Tammacco
  Francesco Quaratino
  Renzo Pampani
          Formazione
  Database
 
                Partners
      http://www.dotnetside.org
 
 
Pubblicazioni »
Come usare la OUTPUT keyword di Sql Server 2005
Sql Server 2005 introduce molte interessanti novità e migliorie nel linguaggio Transact-SQL. Tra queste la parola chiave OUTPUT o OUTPUT...INTO, la quale permette di restituire i valori di database aggiornati a seguito di operazioni di INSERT, UPDATE e DELETE. Questa funzionalità può essere d'aiuto al DBA (o se preferite DBD - DataBase Developer) in diversi situazioni, per esempio, il recupero del valore dei campi di tipo identity e di quelli calcolati. Vediamo degli esempi che adoperano una tabella [Books] che presenta un campo identity [BookID] e un campo calcolato [ProjectedSales].

/* Transact-SQL 2005 */
CREATE SCHEMA OutputSample AUTHORIZATION dbo
CREATE TABLE Books (
BookID int IDENTITY,
Title nvarchar(50) NOT NULL,
Published datetime NOT NULL,
CurrentSales money NOT NULL,
ProjectedSales AS CurrentSales * 0.01 * DATEDIFF (day, Published, GetDate()), ModifiedBy sysname DEFAULT suser_name() NOT NULL
)
GO


Inseriremo un record utilizzando la parola chiave OUTPUT allo scopo di restituire al client il valore del campo identity [BookID], del campo calcolato [ProjectedSales] e di quello valorizzato dal default [ModifiedBy]. Per fare ciò, OUTPUT sfrutta le tabelle virtuali Inserted e Deleted, le stesse esposte nei Trigger: la tabella virtuale Inserted contiene i valori delle righe inserite mediante UPDATE o i nuovi valori delle righe aggiornate mediante UPDATE, mentre la Deleted contiene i valori delle righe cancellate mediante DELETE o i vecchi valori delle righe aggiornate mediante UPDATE.

/* Transact-SQL 2005 */
INSERT INTO OutputSample.Books (Title, Published, CurrentSales)
OUTPUT inserted.BookID, inserted.ProjectedSales, inserted.ModifiedBy
VALUES ('Inside Sql Server 2005', '01-04-2006', 100)
GO


Otterremo il risultato seguente:

BookID ProjectedSales ModifiedBy
----------- --------------------------------------- ---------------
          1 49.000000       XPLAYN\FRANCESCO

(Righe interessate: 1)

Per la verità, già in Sql Server 2000 si disponeva di tre diversi metodi che garantivano un efficace recupero dell'ultimo valore Identity generato all'interno della sessione utente (mediante @@IDENTITY), all'interno dello scope corrente - stored procedure, user function, batch - (mediante SCOPE_IDENTITY()) e, infine, in una qualsiasi tabella del database indipendentemente da sessione e scope (mediante IDENT_CURRENT). In più rispetto a tali metodi, la OUTUPT keyword ci permette di ricavare tutti i valori identity generati in un'inserimento di massa. Ad esempio, supponiamo di voler popolare la tabella [Books] a partire da un'altra tabella chiamata [SourceBooks] che andiamo di seguito a creare e popolare:

/* Transact-SQL 2005 */
CREATE TABLE OutputSample.SourceBooks ( Title nvarchar(50) NOT NULL, Published datetime NOT NULL, CurrentSales money NOT NULL )
GO
INSERT INTO OutputSample.SourceBooks
VALUES ('Transact-SQL in Sql Server 2005', '10-02-2006', 500)
INSERT INTO OutputSample.SourceBooks
VALUES ('Algoritmi e Strutture Dati', '20-01-2005', 1200)
INSERT INTO OutputSample.SourceBooks
VALUES ('Basi di dati 2a Ed.', '01-01-2006', 1500)
GO


Quando popoliamo [Books] a partire da [SourceBooks] mediante la classica istruzione "INSERT INTO ... SELECT" utilizzando OUTPUT:

/* Transact-SQL 2005 */
INSERT INTO OutputSample.Books (Title, Published, CurrentSales)
OUTPUT inserted.BookID, inserted.ProjectedSales, inserted.ModifiedBy
SELECT Title, Published, CurrentSales FROM OutputSample.SourceBooks
GO


otteniamo come risultato:
BookID ProjectedSales ModifiedBy
----------- --------------------------------------- -----------------
          1   495.000000 XPLAYN\FRANCESCO
          2 5820.000000 XPLAYN\FRANCESCO
          3 2085.000000 XPLAYN\FRANCESCO

(Righe interessate: 3)

I valori restituiti dalla OUTPUT keyword possono anche essere registrati in una variabile di tipo tabella oppure una tabella vera e propria. Per fare ciò basterà aggiungere la parola INTO seguita dalla tabella destinazione.

/* Transact-SQL 2005 */
DECLARE @BooksLog TABLE ( BookID int, Title nvarchar(50) NOT NULL, ModifiedBy sysname )
INSERT INTO OutputSample.Books (Title, Published, CurrentSales)
OUTPUT inserted.BookID, inserted.ProjectedSales, inserted.ModifiedBy INTO @BooksLog
VALUES ('.NET Inside', '01-10-2005', 100)
SELECT * FROM @BooksLog
GO


E' facile immaginare un'utilizzo di questa funzionalità in ambito di logging delle operazioni (di cui è possibile vedere una soluzione per Sql Server 2000 nel mio articolo "Log delle transazioni mediante trigger").

 
Autore E-Mail Web Site Data
Francesco Quaratino francesco_AT_xplayn.org www.xplayn.org 20/05/2006
      ©Copyright 2005 - xplayn.org