[sql server] ottenere il parametro di output

lunedì 04 dicembre 2006 - 07.55

escaflowne Profilo | Junior Member

Ciao a tutti,
non capisco cosa non funzioni di questo procedimento; in pratica da vb.net lancio la procedura sql che dovrebbe tornarmi il valore di output ma mi da l'errore (non ci sono valori). Premetto che la procedura funziona correttamente e inserisce nel db la riga corretta.
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

e da vb.net la richiamo in questo modo

sqlComm = New SqlClient.SqlCommand("insDittaToDo", sqlConn) sqlComm.CommandType = CommandType.StoredProcedure 'add input parameter Dim sqlParameter As System.Data.SqlClient.SqlParameter sqlComm.Parameters.AddWithValue("@p1", tool.rep(Me.txtDenominazione.Text)) sqlComm.Parameters.AddWithValue("@p2", tool.rep(Me.txtCodice.Text)) sqlComm.Parameters.AddWithValue("@p3", tool.rep(Me.cmbTipo.Text)) sqlComm.Parameters.AddWithValue("@p4", periodicita) sqlComm.Parameters.AddWithValue("@p5", tool.rep(Me.txtInfo.Text)) sqlComm.Parameters.AddWithValue("@p7", tool.rep(Me.txtIVA.Text)) sqlComm.Parameters.AddWithValue("@p8", 1) 'add output parameter sqlParameter = sqlComm.Parameters.AddWithValue("@idNew", SqlDbType.Int) sqlParameter.direction = ParameterDirection.Output 'execute command Dim dtrElist As System.Data.SqlClient.SqlDataReader dtrElist = sqlComm.ExecuteReader(CommandBehavior.CloseConnection) Dim OutputValue As Integer = Convert.ToInt32(dtrElist("@idNew")) MsgBox(OutputValue)

l'errore lo da sulla penultima riga dicendomi, appunto, "Tentativo non valido di lettura in assenza di dati"
Ribadisco che la insert la fa correttamente

Grazie a tutti

lbenaglia Profilo | Guru

> select @idNewTmp = @@IDENTITY
> set @idNew = @idNewTmp

Punto 1: non utilizzare la funzione @@IDENTITY all'interno di una stored procedure per leggere il valore autogenerato dall'attributo IDENTITY, perché nel caso in cui siano definiti dei triggers nella tabella di destinazione che generano un ulteriore INSERT su un'altra tabella avente anch'essa una colonna numerica con l'attributo IDENTITY, andresti a recuperare quest'ultimo valore in quanto lo scope della funzione @@IDENTITY è la connessione.
Se vuoi essere certo di recuperare il valore autogenerato dal comando di INSERT presente nella stored procedure utilizza la funzione SCOPE_IDENTITY() il cui scope è appunto la procedura stessa.

Punto2: Per quale motivo utilizzi la variabile @idNewTmp? Non potresti semplicemente scrivere SET @idNew = SCOPE_IDENTITY()?

> 'add output parameter
>sqlParameter = sqlComm.Parameters.AddWithValue("@idNew", SqlDbType.Int)
>sqlParameter.direction = ParameterDirection.Output

Mmmmm... non potresti semplicemente scrivere qualcosa del tipo:

Dim parm As New System.Data.SqlClient.SqlParameter("@idNew",SqlDbType.Int) parm.Direction=ParameterDirection.Output cmd.Parameters.Add(parm3)

>Grazie a tutti
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

escaflowne Profilo | Junior Member

>> select @idNewTmp = @@IDENTITY
>> set @idNew = @idNewTmp
>
>Punto 1: non utilizzare la funzione @@IDENTITY all'interno di
>una stored procedure per leggere il valore autogenerato dall'attributo
>IDENTITY, perché nel caso in cui siano definiti dei triggers
>nella tabella di destinazione che generano un ulteriore INSERT
>su un'altra tabella avente anch'essa una colonna numerica con
>l'attributo IDENTITY, andresti a recuperare quest'ultimo valore
>in quanto lo scope della funzione @@IDENTITY è la connessione.
>Se vuoi essere certo di recuperare il valore autogenerato dal
>comando di INSERT presente nella stored procedure utilizza la
>funzione SCOPE_IDENTITY() il cui scope è appunto la procedura
>stessa.
>

Hai ragione, semplicemente non ci sono trigger sulla tabella incriminata. Però hai ragione, è errato

>Punto2: Per quale motivo utilizzi la variabile @idNewTmp? Non
>potresti semplicemente scrivere SET @idNew = SCOPE_IDENTITY()?
>

vero, ho usato questo metodo solo perchè con set @idNew = @@IDENTITY non faceva nulla. Solo una prova

>> 'add output parameter
>>sqlParameter = sqlComm.Parameters.AddWithValue("@idNew", SqlDbType.Int)
>>sqlParameter.direction = ParameterDirection.Output
>
>Mmmmm... non potresti semplicemente scrivere qualcosa del tipo:
>
>Dim parm As New System.Data.SqlClient.SqlParameter("@idNew",SqlDbType.Int)
>parm.Direction=ParameterDirection.Output
>cmd.Parameters.Add(parm3)
>

provo anche così ma, se non sbaglio, anche il mio modo (seppur contorto) dovrebbe funzionare. Giusto?
Secondo te come mai c'è questo problema?

>>Grazie a tutti
>Prego.
>
arigrazie :)

>Ciao!
>--
>Lorenzo Benaglia
>Microsoft MVP - SQL Server
>http://blogs.dotnethell.it/lorenzo/
>http://italy.mvps.org

lbenaglia Profilo | Guru

>Secondo te come mai c'è questo problema?

Allora, ho preparato il seguente esempio:

USE tempdb; GO CREATE TABLE dbo.Students( StudentID int NOT NULL IDENTITY PRIMARY KEY, FirstName varchar(10) NOT NULL, LastName varchar(10) NOT NULL ); GO CREATE PROCEDURE dbo.up_AddStudent( @FirstName varchar(10), @LastName varchar(10), @NewID int OUTPUT ) AS INSERT dbo.Students VALUES(@FirstName, @LastName); SET @NewID = SCOPE_IDENTITY(); GO

Richiamo la sp dbo.up_AddStudent dalla seguente applicazione console scritta in VB.NET:

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

A me funge alla grande
prova a dargli un'occhiata...

>arigrazie :)
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

escaflowne Profilo | Junior Member

Perfetto,
lo provo così vedo dove sta l'inghippo. Grazie mille
(intanto ho risolto cambiando completamente modo di rapportarmi alla stored così che non mi serva più il parametro di output, però vorrei capire dove sta il mio errore così da risolverlo in futuro)

flytouch Profilo | Junior Member

Era una virgola in piu
Grazie Lorenzo
Risolto
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-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5