#45: ADO.NET Leggere la chiave del record appena inserito in SQL Server

Uno dei problemi che più frequentemente mi vengono posti riguarda la possibilità di inserire un nuovo record in una tabella e di conoscere il valore assegnato dal DBMS al campo auto incrementante.

Questo problema è solitamente risolto, peraltro in modo brillante ed elegante, con una specifica stored procedure (SP) di SQL Server. Qualcuno, però, chiede come si può fare direttamente da codice, senza “scomodare” una stored procedure.

Ad un primo esame, non abbiamo la possibilità di inserire il record e subito dopo leggere il valore del campo IDENTITY, perché nel frattempo, tra la nostra scrittura del record e la nostra lettura della chiave, qualche altro utente potrebbe aver inserito un nuovo record.

Queste due operazioni, invece, devono essere fatte in un unico blocco, cioè devono essere eseguite in un’unica transazione (principio di “atomicità” della transazione).

A questo proposito c’è una particolarità di SQL Server che possiamo utilizzare per risolvere questo problema: in T-SQL possono essere eseguite più istruzioni in sequenza, senza soluzione di continuità, semplicemente separando ciascuna istruzione con un punto e virgola (;).

In questo modo le singole istruzioni saranno eseguite una dopo l’altra senza interrompere la transazione e restituendo, così, il corretto valore della colonna IDENTITY.

Un esempio di codice di questa tecnica è il seguente:

      Dim cn As System.Data.SqlClient.SqlConnection
      Dim cnStr = "Data Source = HP\SQL2008EXPRESS;" & _
         "Initial Catalog=NOMEDATABASE;" & _
         "Password=PIPPO;" & _
         "User ID=sa;" & _
         "Persist Security Info=True"
      cn = New System.Data.SqlClient.SqlConnection(cnStr)
      cn.Open()
      Dim cmd As New System.Data.SqlClient.SqlCommand( _
         "SET NOCOUNT ON; INSERT INTO Tabella (ANAnome) " & _
         "VALUES ('De Ghetto Mario'); " & _
         "SELECT SCOPE_IDENTITY() AS ANAID;", cn)
      Dim risultato = cmd.ExecuteScalar()
      MessageBox.Show("Il nuovo ID inserito è " & risultato)
      cn.Close()
      cn = Nothing

Attenzione a impostare correttamente i parametri della stringa di connessione (nome dell’istanza, nome del database, utente e password), altrimenti non potrete collegarvi correttamente alla fonte dati.

Annunci

Pubblicato il 1 ottobre 2008, in ADO.NET, Tips con tag . Aggiungi il permalink ai segnalibri. 2 commenti.

  1. Ciao,
    Ho trovato l’articolo molto interessante, mi chiedevo se funziona anche con database .mdb (access 2003) o solo con sql server. Ho provato ma non sono riuscito a far eseguire più di una istruzione contemporaneamente tramite sql. Grazie

    Mi piace

  2. La tecnica che ho illustrato funziona solo con SQL Server.
    Con Access (database .mdb) non puoi inviare più di un comando SQL alla volta, però puoi eseguire più istruzioni SQL all’interno di una transazione (che bisogna attivare esplicitamente).
    Inoltre devi cambiare le istruzioni SQL, perché SET NOCOUNT non esiste in Access, così come non esiste SCOPE_IDENTITY().
    Prova a dare un’occhiata a questo articolo della Knowledge Base di Microsoft: http://support.microsoft.com/default.aspx/kb/815629/en-us. Dovrebbe aiutarti a fare la stessa cosa con una tabella di Access da VB.NET.
    Attenzione che l’accesso, nell’articolo, avviene tramite le librerie JET che devi aver installato (e che non funzionano su Windows a 64 bit, se non compilando a 32 bit).

    Mi piace

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger hanno fatto clic su Mi Piace per questo: