Recuperare id subito dopo una insert in pagina aspx.

domenica 22 giugno 2008 - 18.07

86Marco Profilo | Expert

Salve. Ho un problema per me piuttosto serio che mi blocca la realizzazione di un progettino in asp.net
La mia applicazione è interfacciata su di un database che ha i seguenti campi: IDCLIENTE, NOMINATIVO e INDIRIZZO.

Ho costrutito una pagina aspx che mi consente l'inserimento del nominativo e dell'indirizzo del cliente e tramite un controllo button mi viene eseguita una stored procedure che mi inserisce i dati nel database.
Fin qui tutto bene.

Il mio problema nasce quando ho di bosngno che al click del pulsante che mi esegue l'inserimento dei dati nel database, mi deve automaticamente comunicare l'ID che è stato assegnato al record appena inserito.

Come è possibile farlo?
Vi prego rispondete xche è importante.
Mille grazie

Stroke Profilo | Junior Member

Aggiungi alla tua sp
RETURN @@IDENTITY
ti ritorna ilcampo chiave progressivo
ciao
Furio
http://www.opsi.ws

alx_81 Profilo | Guru

>Salve.
Ciao!

>Il mio problema nasce quando ho di bosngno che al click del
>pulsante che mi esegue l'inserimento dei dati nel database, mi
>deve automaticamente comunicare l'ID che è stato assegnato al
>record appena inserito.
>Come è possibile farlo?
Se stai parlando di sql server, basta fare una stored procedure che valorizzi un parametro di OUTPUT con l'id appena inserito. Prendi questo esempio:

USE tempdb; GO CREATE TABLE dbo.ElencoID ( ID int IDENTITY(1,1) NOT NULL , Valore varchar(3) NOT NULL , CONSTRAINT PK_ElencoID PRIMARY KEY CLUSTERED ( ID ) ) GO INSERT INTO dbo.ElencoID (Valore) VALUES ('AAA') INSERT INTO dbo.ElencoID (Valore) VALUES ('BBB') INSERT INTO dbo.ElencoID (Valore) VALUES ('CCC') INSERT INTO dbo.ElencoID (Valore) VALUES ('DDD') INSERT INTO dbo.ElencoID (Valore) VALUES ('EEE') GO IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id('dbo.proc_InserisciETornaID')) DROP PROCEDURE dbo.proc_InserisciETornaID GO CREATE PROCEDURE dbo.proc_InserisciETornaID @Valore varchar(3) , @ID int = NULL OUTPUT AS BEGIN SET NOCOUNT ON; INSERT INTO dbo.ElencoID (Valore) VALUES (@Valore) SET @ID = SCOPE_IDENTITY() END GO -- chiamata alla stored procedure DECLARE @IDOut int EXEC dbo.proc_InserisciETornaID 'YYY', @IDOut OUTPUT -- id inserito SELECT @IDOut as IDInserito GO -- chiamata alla stored procedure DECLARE @IDOut int EXEC dbo.proc_InserisciETornaID 'ZZZ', @IDOut OUTPUT -- id inserito SELECT @IDOut as IDInserito GO -- Pulizia --DROP TABLE ElencoID --GO

Con una stored procedure così fatta, puoi usare il namespace System.Data.SQLClient in questo modo per ottenere l'id appena inserito:

C#
-------------------------------------
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

>Mille grazie
di nulla!

--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

alx_81 Profilo | Guru

>Aggiungi alla tua sp
>RETURN @@IDENTITY
>ti ritorna ilcampo chiave progressivo
Attenzione Furio, non è sempre corretto utilizzare @@IDENTITY.
E' preferibile la funzione SCOPE_IDENTITY() che vale nello scope corrente, la @@IDENTITY ti torna l'ultimo ID inserito in una transazione completa.
Prova a pensare se la tabella su cui inserisci il record avesse un trigger che inserisce un altro record in un'altra tabella con identity.
In quel caso, l'id ritornato dalla @@IDENTITY sarebbe quello del record inserito nel trigger, e quindi quello che non ti serve.
Osserva il seguente esempio:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


E dai una letta a questo link :
http://technet.microsoft.com/it-it/library/ms190315.aspx

Ciao!
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

86Marco Profilo | Expert

Bhe prendendo per ora in considerazione la risposta di furio (solo perchè per ora richiede meno codice), non è ke mi potresti aiutare a capire effettivamente come far restituire la collonna identntity con return?
In poche parole vorrei sapere il codice esatto... se possibile... grazie furio

Grazie mille anche ad alex, il suo intervento è statoo stampato e cercherò di capirlo ed interpretarlo nel breve tempo possibile.

Marco

alx_81 Profilo | Guru

>Bhe prendendo per ora in considerazione la risposta di furio
>(solo perchè per ora richiede meno codice), non è ke mi potresti
>aiutare a capire effettivamente come far restituire la collonna
>identntity con return?
>In poche parole vorrei sapere il codice esatto... se possibile...
86Marco, se copi ed incolli il mio codice, cambi il nome della stored procedure e aggiungi un parametro di output alla tua, è fatta.
E comunque non usare @@IDENTITY, ma SCOPE_IDENTITY(). E sei sempre sicuro.

--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

Stroke Profilo | Junior Member

Ha ragione Alessandro se la store procedure è complessa.

In ogni caso mi pare di capire nel tuo inetrrogativo che vuoi sapere come gestire il return della SP.

Inserisci nei parametri della sp
TuaStoreProcedure.Parameters.AddWithValue("@RETURN_VALUE", SqlDbType.Int).Direction = ParameterDirection.ReturnValue

e dopo
TuaStoreProcedure.ExecuteNonQuery()

Dim retVal As Integer = Fix(TuaStoreProcedure.Parameters("@RETURN_VALUE").Value)
Spero di esserti stato utile.
ciao
Furio
http://www.opsi.ws

rossimarko Profilo | Guru

>Aggiungi alla tua sp
>RETURN @@IDENTITY
>ti ritorna ilcampo chiave progressivo


Ciao,

scusate se intervengo ma questa passo è importante. Ritornare @@IDENTITY come già detto da Alessandro non è corretto.
Bisogna usare la SCOPE_IDENTITY e la spiegazione la potete vedere nel post che ha già fatto lui. Ritornare un valore potenzialmente non corretto è molto pericoloso!

Per quanto riguarda la gestione forse non vi siete capiti. La gestione della stored rimane banale, basterebbe ritornare la SCOPE_IDENTITY() invece che @@IDENTITY. In alternativa si può impostare un parametro di OUTPUT come diceva Alessandro, e utilizzare il parametro di ritorno per altri scopi.

La gestione lato vb è identitica, ovvero invece che dichiarare una parametro di tipo ReturnValue dovresti dichiare un parametro di Output
-----------------------------------------
Rossi Marco
http://blogs.dotnethell.it/rossimarko

86Marco Profilo | Expert

Ciao Furio
vediamo se cosi riesci ad aiutarmi meglio:; questo è il codice che ho inserito nel mio evento Click di un button

Dim datasource As New SqlDataSource
datasource.ConnectionString = ConfigurationManager.ConnectionStrings("DatabaseConnectionString1").ToString
datasource.InsertCommandType = SqlDataSourceCommandType.StoredProcedure
datasource.InsertCommand = "StoredProcedure1"
datasource.InsertParameters.Add("Nome", TextBox1.Text)
datasource.InsertParameters.Add("Cognome", TextBox2.Text)

datasource.Insert()


Come faccio ora a ricavare il contatore che è stato assegnato al record.?
Grazie

Stroke Profilo | Junior Member

Questa è la funzione

Public Function RendimiIlCodice(ByVal Nome As String, ByVal Cognome As String) As Integer

' Creo una istanza di connessione e un oggetto command
Dim Connessione As New SqlConnection(ConfigurationManager.ConnectionStrings("GustoAMonteConnectionString").ConnectionString)
Dim cmdVoglioIlcodice As New SqlCommand("StoreProcedure1", Connessione)

' SP
cmdVoglioIlcodice.CommandType = CommandType.StoredProcedure

' Parametri
cmdVoglioIlcodice.Parameters.AddWithValue("@RETURN_VALUE", SqlDbType.Int).Direction = ParameterDirection.ReturnValue
cmdVoglioIlcodice.Parameters.AddWithValue("@Nome", Nome)
cmdVoglioIlcodice.Parameters.AddWithValue("@Cognome", Cognome)

' Esegue
Connessione.Open()
cmdVoglioIlcodice.ExecuteNonQuery()
Dim retVal As Integer = Fix(cmdVoglioIlcodice.Parameters("@RETURN_VALUE").Value)
Connessione.Close()
Return retVal
End Function



Quando ti serve
dim codice as integer = RendimiIlCodice(TextBox1.text, TextBox2.text)

Nella SP inserisci
return SCOPE_IDENTITY()

Come mai hai instanziato un datasource? A cosa ti serve?
Alessandro più o meno ti aveva scritto la stessa cosa.

Spero di esserti stato utile

ciao


Furio
http://www.opsi.ws
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5