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

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

  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"

Lascia un commento

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.