Newsgroup: it.comp.lang.visual-basic
Titolo: Transazioni in SP e valore di ritorno

Salve a tutti, ho un problema con una transazione e il codice di errore. 
In pratica apro una transazione in VB tramite la connessione, aggiorno 
prima una tabella tramite un rs e poi tramite una SP aggiorno un'altra 
tabella. Poi se non ci sono errori faccio la commit, altrimenti la 
rollback, Niente di particolare direte voi...il punto è che se viene 
scatenato un errore dal rs riesco a gestirlo senza problemi (un bel "on 
error goto" ) e faccio la rollback. Se invece l'errore è nella stored, 
non riesco a farmi tornare nessun codice d'errore, in verità non mi 
ritorna assolutamente nulla: come se niente fosse successo, tutti i 
parametri di output sono a "null"...Ma non è finita quaa, tornando in VB
  il codice continua l'esecuzione senza problemi....e fa pure la 
committrans!!Salvo poi effettivamente (dal momento che c'era un errore 
nella stored) fare un rollback sia dei dati modificati dal rs che di 
quelli modificati dalla SP....non so se sia un comportamento anomalo o 
cosa.....

parametri di output sono a "null"..
Potresti gestire l'errore all'interno della stored procedure.
-- 
ciao, un hal di passaggio

 Potresti gestire l'errore all'interno della stored procedure.
Così più o meno:
IF @@error > 0
	BEGIN
	RollBack tran
	set @MyErr = @@Error
	END
dove @MyErr è un valore di output. Il rollback lo fa, ma vorrei farmi 
ritornare un valore di errore, un qualcosa....Se inizializzo all'inizio 
della Sp @MyErr a "0" per esempio, se non c'è errore ritorna "0" se c'è 
un errore ritorna "null" comunque...E'vero che da VB posso vedere si 
MyErr è "null", ma non mi sembra molto pulito.
Ciao e grazie
Edoardo


Puoi usare il valore di return.
Di seguito ti riporto il codice vb di una funzione che utilizzo per il
richiamo di una stored procedure:
Public Function ImportTabelle(nomefile As String, nomegiacenze As String) As
Integer
Dim Cmd As New ADODB.Command
With Cmd
    Set .ActiveConnection = dfwConn
    .CommandType = adCmdStoredProc
    .CommandText = "ImportTabelle"
    .Parameters.Append .CreateParameter("RetVal", adInteger,
adParamReturnValue)
    .Parameters.Append .CreateParameter("NomeFile", adVarChar, adParamInput,
255, nomefile)
    .Parameters.Append .CreateParameter("NomeFileGiacenze", adVarChar,
adParamInput, 255, nomegiacenze)
    Call .Execute
    ImportTabelle = .Parameters("RetVal").Value
End With
Set Cmd = Nothing
End Function
Della stored procedure ti riporto solo i pezzi importanti perchè se no
sarebbe un pò troppo lunga:
Declare @RetVal as int
Set @RetVal = 0
SET XACT_ABORT ON
BEGIN TRANSACTION
...codice...
DELETE GIACENZA
if @@error>0
begin
 set @RetVal = -1
 goto Uscita
end
...altro codice...
Uscita:
if @RetVal=0
 COMMIT TRANSACTION
else
 ROLLBACK TRANSACTION
return @RetVal

ritornare un valore di errore, un qualcosa....
Non ho capito se ti interessa che la stored procedure ritorni una
valore, ad esempio
	return @MyErr
oppure un'eccezione, come
	IF @MyErr <> 0
	   BEGIN
   	     RAISERROR ('Errore %d', 16, 1, @MyErr)
             ROLLBACK TRANSACTION
	   END


 	   END
Il raiserror notifica l'errore a chi di preciso? Se è richiamata 
direttamente da VB, come posso catturarlo? Ho provato e non ho visto 
niente, ne msgbox ne log sul server...

 return @RetVal
Ok, d'accordo, il fatto è che non mi ritorna nessun valore, tutti i 
parametri di output sono a "null", in qualsiasi modo li faccia 
ritornare, non ritrna nulla, nemmeno il valore con cui avevo 
inizializzato le variabili all'inizio della SP. Al momento mi accontento
  del fatto che mi ritorni valori "null"....
Ciao e grazie
Edoardo

direttamente da VB, come posso catturarlo?
Lo dovresti catturare come qualsiasi altra eccezione, cioe' con il
classico On Error. Puoi avere dettagli sull'errore analizzando la
collezione Errors della Connection.



C'è qualche GO in mezzo alla SP?
Ciao
Alberto

 C'č qualche GO in mezzo alla SP?
No....ho provato con una SP di rpiva che fa semplicemente un inserimento...

 che ti aspetti.
la stored č questa
[code]
Alter Procedure dbo.sp_prova
	(
	@Nome varchar,
	@Cognome varchar,
	@MyErr INT OUTPUT
	)
As
SET @MyErr = 0
/*inserimento corretto*/
INSERT INTO Prova2 (P2CodArt, P2Descri)
VALUES ('Pippo','pappo')
/*qua c'č un errore, P1Cognome č un campo int e non varchar come cognome*/
INSERT INTO Prova1 (P1Nome, P1Cognome)
VALUES (@Nome,@Cognome)
IF @@error > 0
	BEGIN
	set @MyErr = @@Error
	return @MyErr
	END
[/code]
Se commento il codice con l'errore MyErr contiene "0", se invece lascio 
  l'errore contiene "null"....
Ciao e grazie
Edoardo


Hai provato a fare il debug della SP per vedere come mai non ti ritorna il
valore ?
Qualche errore dovrebbe dartelo...

 la stored è questa
SET XACT_ABORT
Specifies whether Microsoft® SQL ServerT automatically rolls back the
current transaction if a Transact-SQL statement raises a run-time error.
Syntax
SET XACT_ABORT{ON | OFF}
Remarks
When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time
error, the entire transaction is terminated and rolled back. When OFF, only
the Transact-SQL statement that raised the error is rolled back and
transaction continues processing. Compile errors, such as syntax errors, are
not affected by SET XACT_ABORT.
It is recommended that XACT_ABORT be set ON when executing data modification
statements against remote tables in an implicit or explicit transaction. For
more information, see Distributed Queries and Distributed Transactions.
The setting of SET XACT_ABORT is set at execute or run time and not at parse
time.

 SET XACT_ABORT
Non avevo settato XACT_ABORT, ma sia messo a On che a Off, non cambia, 
non ritorna nessun valore comunque....
Ciao

 non ritorna nessun valore comunque....
e se inverti l'ordine?
set @MyErr = @@Error
IF @MyErr > 0
return @MyErr
Ciao
Alberto

 ha scritto nel messaggio
news:c41o5e$2e4sf6$1...@ID-222113.news.uni-berlin.de...

Purtroppo il problema è dovuto al fatto che c'è un errore di sintassi e
questo provoca l'interruzione dell'esecuzione della stored procedure.
L'errore generato ha un livello di severity che provoca la chiusura della
connection e quindi si ferma immediatamente l'esecuzione restituendo null.

 connection e quindi si ferma immediatamente l'esecuzione restituendo null.
Intendi dire che se fosse un altro errore mi ritorna correttamente il 
codice di errore?
E in tal caso come faccio: dovrei gestire sia il "null" che l'eventuale 
codice di errore? Inoltre la connection non viene chiusa, VB continua 
l'esecuzione del codice e fa pure "CommitTrans" (anche se in verità 
annulla tutte le operazioni)
Ciao


Si se fosse un errore di minore importanza di sicuro te lo ritornerebbe. Se
provi ad aprire da VB un recordset in ReadOnly e tenti di fare un'update
sulla stessa tabella da una SP dovrebbe ritornati un errore (non ho provato,
ma sinceramente non mi veniva in mente nessun altro esempio per provare gli
errori).
Se il VB non intercetta l'errore con l'on error non ti resta che controllare
il null.
No, la connection che fai da VB non viene chiusa... Avevo letto che chiudeva
anche la connection ma ho provato con il debug di SQL Analyzer e in realtà
la connection la chiude quando chiudo il debug.