Je rencontre un problème pour renvoyer un paramètre de sortie d'une procédure stockée Sql Server dans une variable C #. J'ai lu les autres articles à ce sujet, pas seulement ici, mais sur d'autres sites, et je ne peux pas le faire fonctionner. Voici ce que j'ai actuellement. Actuellement, j'essaie simplement d'imprimer la valeur qui revient. Le code suivant renvoie une valeur null. Ce que j'essaie de retourner est la clé primaire. J'ai essayé d'utiliser @@IDENTITY
et SCOPE_INDENTITY()
(c'est-à-dire SET @NewId = SCOPE_IDENTITY()
).
Procédure stockée:
CREATE PROCEDURE usp_InsertContract
@ContractNumber varchar(7),
@NewId int OUTPUT
AS
BEGIN
INSERT into [dbo].[Contracts] (ContractNumber)
VALUES (@ContractNumber)
Select @NewId = Id From [dbo].[Contracts] where ContractNumber = @ContractNumber
END
Ouverture de la base de données:
pvConnectionString = "Server = Desktop-PC\\SQLEXPRESS; Database = PVDatabase; User ID = sa;
PASSWORD = *******; Trusted_Connection = True;";
try
{
pvConnection = new SqlConnection(pvConnectionString);
pvConnection.Open();
}
catch (Exception e)
{
databaseError = true;
}
Exécuter la commande:
pvCommand = new SqlCommand("usp_InsertContract", pvConnection);
pvCommand.Transaction = pvTransaction;
pvCommand.CommandType = CommandType.StoredProcedure;
pvCommand.Parameters.Clear();
pvCommand.Parameters.Add(new SqlParameter("@ContractNumber", contractNumber));
SqlParameter pvNewId = new SqlParameter();
pvNewId.ParameterName = "@NewId";
pvNewId.DbType = DbType.Int32;
pvNewId.Direction = ParameterDirection.Output;
pvCommand.Parameters.Add(pvNewId);
try
{
sqlRows = pvCommand.ExecuteNonQuery();
if (sqlRows > 0)
Debug.Print("New Id Inserted = ",
pvCommand.Parameters["@NewId"].Value.ToString());
}
catch (Exception e)
{
Debug.Print("Insert Exception Type: {0}", e.GetType());
Debug.Print(" Message: {0}", e.Message);
}
}
J'ai légèrement modifié votre procédure stockée (pour utiliser SCOPE_IDENTITY
) et cela ressemble à ceci:
CREATE PROCEDURE usp_InsertContract
@ContractNumber varchar(7),
@NewId int OUTPUT
AS
BEGIN
INSERT INTO [dbo].[Contracts] (ContractNumber)
VALUES (@ContractNumber)
SELECT @NewId = SCOPE_IDENTITY()
END
J'ai essayé ceci et cela fonctionne très bien (avec cette procédure stockée modifiée):
// define connection and command, in using blocks to ensure disposal
using(SqlConnection conn = new SqlConnection(pvConnectionString ))
using(SqlCommand cmd = new SqlCommand("dbo.usp_InsertContract", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
// set up the parameters
cmd.Parameters.Add("@ContractNumber", SqlDbType.VarChar, 7);
cmd.Parameters.Add("@NewId", SqlDbType.Int).Direction = ParameterDirection.Output;
// set parameter values
cmd.Parameters["@ContractNumber"].Value = contractNumber;
// open connection and execute stored procedure
conn.Open();
cmd.ExecuteNonQuery();
// read output value from @NewId
int contractID = Convert.ToInt32(cmd.Parameters["@NewId"].Value);
conn.Close();
}
Est-ce que cela fonctionne aussi dans votre environnement? Je ne peux pas dire pourquoi votre code original ne fonctionnera pas - mais lorsque je le fais ici, VS2010 et SQL Server 2008 R2, cela fonctionne parfaitement ...
Si vous ne récupérez pas de valeur, alors je soupçonne que votre table Contracts
ne contient peut-être pas vraiment une colonne avec la propriété IDENTITY
.
Avant de changer la procédure stockée, veuillez vérifier quelle est la sortie de votre procédure actuelle. Dans SQL Server Management, exécutez les actions suivantes:
DECLARE @NewId int
EXEC @return_value = [dbo].[usp_InsertContract]
N'Gary',
@NewId OUTPUT
SELECT @NewId
Voir ce qu'il retourne. Cela peut vous donner une idée de la raison pour laquelle votre paramètre de sortie n'est pas rempli.
Procédure stockée.........
CREATE PROCEDURE usp_InsertContract
@ContractNumber varchar(7)
AS
BEGIN
INSERT into [dbo].[Contracts] (ContractNumber)
VALUES (@ContractNumber)
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
END
C #
pvCommand.CommandType = CommandType.StoredProcedure;
pvCommand.Parameters.Clear();
pvCommand.Parameters.Add(new SqlParameter("@ContractNumber", contractNumber));
object uniqueId;
int id;
try
{
uniqueId = pvCommand.ExecuteScalar();
id = Convert.ToInt32(uniqueId);
}
catch (Exception e)
{
Debug.Print(" Message: {0}", e.Message);
}
}
EDIT: "Je récupère toujours une valeur DBNull ... L'objet ne peut pas être converti de DBNull vers d'autres types. Je reprendrai cela demain. Je pars pour mon autre travail"
Je crois que la colonne Id de votre table SQL n'est pas une colonne d'identité.
Dans votre code C #, vous utilisez transaction pour la commande . Commencez par la transaction, puis accédez à la valeur de votre paramètre pour obtenir la valeur . :)