Return ID on INSERT? Return ID on INSERT? sql-server sql-server

Return ID on INSERT?


You just need to add @ID to the params collection and then retrieve it like this,

cmd.Parameters.Add("@ID", SqlDbType.Int, 4).Direction = ParameterDirection.Output;cmd.ExecuteNonQuery();//Now just read the value of: cmd.Parameters["@ID"].value

Or, if you prefer this syntax:

SqlParameter param = new SqlParameter("@ID", SqlDbType.Int, 4);param.Direction = ParameterDirection.Output;cmd.Parameters.Add(param);


Since SQL Server 2008 there was an OUTPUT clause added to the syntax of TSQL. This allows you to have the data which is affected by the DML query added to the Tabular Data Stream.

Although querying SCOPE_IDENTITY() after a query returns the correct information it forces SQL Server to execute 2 queries where the output clause limits this to one query.

Knowing this, the query being executed can be altered as follows (Assuming [Id] is the name of the identity):

INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated) OUTPUT INSERTED.IdVALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date)

Another issue is not disposing of the SqlCommand. Most of the Sql... objects in ADO.net implement IDisposable and should be disposed of properly.

Bringing everything together I would implement this piece of code as follows:

        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();        }


You have two options; you could declare an Output parameter called @ID; or - you could change the end to SELECT SCOPE_IDENTITY() and just use:

int id = (int)cmd.ExecuteScalar();

I prefer the formal parameter approach, but ExecuteScalar works well.