Je sais qu'il existe une autre question portant à peu près le même titre, mais elle ne répond pas à ma question ..__ J'ai une procédure stockée, qui renvoie l'identificateur unique après l'insertion (@@ identity). Je l'ai essayé dans l'explorateur de serveur et cela fonctionne comme prévu (@RETURN_VALUE = [identificateur]) . Dans mon code, j'ai ajouté un paramètre appelé "@RETURN_VALUE", avec la direction ReturnValue en premier, que tout autre paramètre, mais quand je exécuter ma requête avec ExecuteNonQuery (), ce paramètre reste vide. Je ne sais pas ce que j'ai fait de mal… .. Mon SPROC:
ALTER PROCEDURE dbo.SetAuction
(
@auctionID int,
@itemID int,
@auctionType tinyint,
@reservationPrice int,
@maxPrice int,
@auctionEnd datetime,
@auctionStart datetime,
@auctionTTL tinyint,
@itemName nchar(50),
@itemDescription nvarchar(MAX),
@categoryID tinyint,
@categoryName nchar(50)
) AS
IF @auctionID <> 0
BEGIN
BEGIN TRAN T1
UPDATE Auction
SET AuctionType = @auctionType,
ReservationPrice = @reservationPrice,
MaxPrice = @maxPrice,
AuctionEnd = @auctionEnd,
AuctionStart = @auctionStart,
AuctionTTL = @auctionTTL
WHERE AuctionID = @auctionID;
UPDATE Item
SET
ItemName = @itemName,
ItemDescription = @itemDescription
WHERE
ItemID = (SELECT ItemID FROM Auction WHERE AuctionID = @auctionID);
COMMIT TRAN T1
RETURN @auctionID
END
ELSE
BEGIN
BEGIN TRAN T1
INSERT INTO Item(ItemName, ItemDescription, CategoryID)
VALUES(@itemName, @itemDescription, @categoryID);
INSERT INTO Auction(ItemID, AuctionType, ReservationPrice, MaxPrice, AuctionEnd, AuctionStart, AuctionTTL)
VALUES(@@IDENTITY,@auctionType,@reservationPrice,@maxPrice,@auctionEnd,@auctionStart,@auctionTTL);
COMMIT TRAN T1
RETURN @@IDENTITY
END
Et mon code est:
cmd.CommandText = cmdText;
SqlParameter retval = new SqlParameter("@RETURN_VALUE", System.Data.SqlDbType.Int);
retval.Direction = System.Data.ParameterDirection.ReturnValue;
cmd.Parameters.Add(retval);
cmd.Parameters.AddRange(parameters);
cmd.Connection = connection;
connection.Open();
cmd.ExecuteNonQuery();
return (int)cmd.Parameters["@RETURN_VALUE"].Value;
Juste essayé sur ma boîte et cela fonctionne pour moi:
Dans SQL Server:
DROP PROCEDURE TestProc;
GO
CREATE PROCEDURE TestProc
AS
RETURN 123;
GO
En C #
string cnStr = "Server=.;Database=Sandbox;Integrated Security=sspi;";
using (SqlConnection cn = new SqlConnection(cnStr)) {
cn.Open();
using (SqlCommand cmd = new SqlCommand("TestProc", cn)) {
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter returnValue = new SqlParameter();
returnValue.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(returnValue);
cmd.ExecuteNonQuery();
Assert.AreEqual(123, (int)returnValue.Value);
}
}
J'ai résolu le problème: vous devez définir SqlCommand.CommandType
sur CommandType.StoredProcedure
pour obtenir les valeurs de retour et/ou les paramètres de sortie. Je n'ai trouvé aucune documentation à ce sujet, mais maintenant tout fonctionne.
Avez-vous la valeur EXEC
dans TSQL? Je me demande si le refactoring de TSQL pourrait aider (et utiliser SCOPE_IDENTITY()
:
alors changez:
COMMIT TRAN T1
RETURN @@IDENTITY
à:
SET @auctionID = SCOPE_IDENTITY()
COMMIT TRAN T1
RETURN @auctionID
(Je voudrais aussi changer l'autre @@IDENTITY
en SCOPE_IDENTITY()
)
En guise d’optimisation mineure, vous pouvez également utiliser:
return (int)retval.Value;
mais ce côté des choses devrait aurait travaillé "tel quel" d'après ce que je peux voir (d'où la raison pour laquelle je me concentre sur TSQL).
Certains peuvent également utiliser cette méthode simple et courte pour calculer la valeur de retour de SP
En SQL:
Create Table TestTable
(
Int Id
)
CREATE PROCEDURE Proc_TestProc
@Id
AS
Begin
Set NOCOUNT ON //Use this line if you don't want to return any message from SQL
Delete from TestTable where Id = @Id
return 1
Set NOCOUNT OFF //NOCOUNT OFF is Optional for NOCOUNT ON property
End
Sql Server renvoie toujours la valeur de type Int uniquement.
et en C #
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["TestConnectionString"].ToString()))
using (SqlCommand cmd = new SqlCommand("Proc_TestProc", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@Id", 1);
var returnParameter = cmd.Parameters.Add("@ReturnVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
conn.Open();
cmd.ExecuteNonQuery();
var result = returnParameter.Value;
}
Vous pouvez également vérifier votre valeur de retour en SQL en utilisant cette commande:
DECLARE @return_status int;
EXEC @return_status = dbo.[Proc_TestProc] 1;
SELECT 'Return Status' = @return_status;
print 'Returned value from Procedure: ' + Convert(varchar, @return_status); // Either previous or this line both will show you the value of returned value
vous pouvez utiliser des méthodes standard que vous utilisiez auparavant dans les requêtes normales, mais dans la commande SQL, vous devez écrire EXEC avant le nom de votre procédure de stockage et ne pas utiliser le type de commande suivant:
SqlConnection con = new SqlConnection(["ConnectionString"])
SqlCommand com = new SqlCommand("EXEC _Proc @id",con);
com.Parameters.AddWithValue("@id",["IDVALUE"]);
con.Open();
SqlDataReader rdr = com.ExecuteReader();
ArrayList liste = new ArrayList();
While(rdr.Read())
{
liste.Add(rdr[0]); //if it returns multiple you can add them another arrays=> liste1.Add(rdr[1]) ..
}
con.Close();