J'ai une requête INSERT et je veux que la base de données retourne l'ID de la ligne que je viens d'insérer.
sqlString = "INSERT INTO MagicBoxes (OwnerID, Key, Name, Permissions, Active, LastUpdated) VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) SET @ID = SCOPE_IDENTITY();";
cmd = new SqlCommand(sqlString, con);
cmd.Parameters.AddWithValue("@OwnerID", OwnerID);
cmd.Parameters.AddWithValue("@BoxKey", BoxKey);
cmd.Parameters.AddWithValue("@BoxName", BoxName);
cmd.Parameters.AddWithValue("@Username", Username);
cmd.Parameters.AddWithValue("@Date", DateTime.Now);
cmd.ExecuteNonQuery();
J'ai actuellement ceci, je ne suis pas sûr de ce que je dois faire ensuite ...
Il vous suffit d’ajouter @ID à la collection params puis de le récupérer comme ceci,
cmd.Parameters.Add("@ID", SqlDbType.Int, 4).Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
//Now just read the value of: cmd.Parameters["@ID"].value
Ou, si vous préférez cette syntaxe:
SqlParameter param = new SqlParameter("@ID", SqlDbType.Int, 4);
param.Direction = ParameterDirection.Output;
cmd.Parameters.Add(param);
Vous avez deux options. vous pouvez déclarer un paramètre Output
appelé @ID
; ou - vous pouvez changer la fin en SELECT SCOPE_IDENTITY()
et simplement utiliser:
int id = (int)cmd.ExecuteScalar();
Je préfère l’approche paramétrique formelle, mais ExecuteScalar
fonctionne bien.
Depuis SQL Server 2008, une clause OUTPUT a été ajoutée à la syntaxe de TSQL. Cela vous permet d'ajouter les données affectées par la requête DML au flux de données tabulaire.
Bien que l'interrogation de SCOPE_IDENTITY () après une requête renvoie les informations correctes, elle oblige SQL Server à exécuter 2 requêtes lorsque la clause de sortie le limite à une requête.
Sachant cela, la requête en cours d'exécution peut être modifiée comme suit (en supposant que [Id]
est le nom de l'identité):
INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated)
OUTPUT INSERTED.Id
VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date)
Un autre problème est de ne pas disposer de la variable SqlCommand
. La plupart des objets Sql...
dans ADO.net implémentent IDisposable
et doivent être éliminés correctement.
En réunissant tout, je mettrais en œuvre ce code comme suit:
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["db"].ConnectionString))
using (var cmd = new SqlCommand(@"
INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated)
OUTPUT INSERTED.Id
VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) ", conn))
{
cmd.Parameters.AddRange(new[]
{
new SqlParameter("@OwnerID", SqlDbType.Int).Value = OwnerID,
new SqlParameter("@BoxKey", SqlDbType.VarChar).Value = BoxKey,
new SqlParameter("@BoxName", SqlDbType.VarChar).Value = BoxName,
new SqlParameter("@Date", SqlDbType.DateTime).Value = DateTime.Now
});
conn.Open();
var id = (int)cmd.ExecuteScalar();
}
Ajoutez ceci à vos paramètres
SqlParameter IDParameter = new SqlParameter("@ID",SqlDbType.Int);
IDParameter.Direction = ParameterDirection.Output;
cmd.Parameters.Add(IDParameter);
Après exécution, vous pouvez récupérer l'identifiant
int id = (int)IDParameter.Value;
Pourquoi appelez-vous pas la procédure de magasin. Transmettez les valeurs à la procédure de stockage pour obtenir les valeurs insérées et à partir du SP, renvoyez la dernière valeur de départ insérée à l'aide de SCOPE_IDENTITY().
J'espère que cette aide est disponible.