19
public static void CreateSocialGroup(string FBUID)
{
    string query = "INSERT INTO SocialGroup (created_by_fbuid) VALUES (@FBUID); SELECT @@IDENTITY AS LastID";

    using (SqlConnection connection = new SqlConnection(ConnectionString))
    {
        SqlCommand command = new SqlCommand(query, connection);
        command.Parameters.AddWithValue("@FBUID", FBUID);

        connection.Open();
        command.ExecuteNonQuery();
    }
}

Is this the right way to do it? And how do i get LastID in to a variable? Thanks

gbn
  • 422,506
  • 82
  • 585
  • 676
Johan
  • 203
  • 1
  • 2
  • 4
  • possible duplicate of [How to get last inserted id?](http://stackoverflow.com/questions/5228780/how-to-get-last-inserted-id) – 200_success Aug 13 '14 at 08:07

9 Answers9

26

OUTPUT clause?

string query = "INSERT INTO SocialGroup (created_by_fbuid) 
                OUTPUT INSERTED.IDCol  --use real column here
                VALUES (@FBUID)";
...
int lastId = (int)command.ExecuteScalar();
gbn
  • 422,506
  • 82
  • 585
  • 676
  • Works, but i get 2 rows inserted, why? – Johan May 24 '11 at 11:52
  • @Johan: it is being called twice somewhere. The SQL given inserts one row only. – gbn May 24 '11 at 11:55
  • 1
    it might be better to use SCOPE_IDENTITY() rather than OUTPUT as OUTPUT will give you errors in case you have triggers set on the table (as stated on [this question link](http://stackoverflow.com/questions/330707/how-to-insert-a-record-and-return-the-newly-created-id-using-a-single-sqlcommand)) – marquito Jul 31 '12 at 12:23
10

You can use ExecuteScalar to get the last value from a Sqlcommand.

The scope_identity() function is safer than @@identity.

faester
  • 14,886
  • 5
  • 45
  • 56
8

If your server supports the OUTPUT clause you could try it with this one:

public static void CreateSocialGroup(string FBUID)
{
    string query = "INSERT INTO SocialGroup (created_by_fbuid) OUTPUT INSERTED.IDENTITYCOL VALUES (@FBUID)";

    using (SqlConnection connection = new SqlConnection(ConnectionString))
    {
        SqlCommand command = new SqlCommand(query, connection);
        command.Parameters.AddWithValue("@FBUID", FBUID);

        connection.Open();
        var _id = command.ExecuteScalar();
    }
}
Oliver
  • 43,366
  • 8
  • 94
  • 151
  • INSERTED.IDENTITYCOL doesn't work in SQL Azure. However if your identity column is named for example 'ID' then INSERTED.ID works! – Adrian Toman Jul 07 '12 at 01:58
5

Personally, I would re-write your code to use Parameters. You could either use an InputOutput parameter or an Output Parameter. However, using a Return Value in your SQL would also work.

Full examples on this can be found on MSDN.

I would also use Scope_Identity() rather than @@Identity this will ensure that you will reveice the ID that relates to the current transaction. Details on Scope_Identity can be found here.

codingbadger
  • 42,678
  • 13
  • 95
  • 110
3

U can try ExecuteScalar for getting the LastID value.

varadarajan
  • 514
  • 1
  • 3
  • 9
2

I'd recommend to use a stored procedure to do this. You can give it an OUTPUT parameter which you can use to return the id value back to your app.

takrl
  • 6,356
  • 3
  • 60
  • 69
0
cmd = new SqlCommand("Insert into table values (1,2,3); SELECT SCOPE_IDENTITY()", conn);

lastRecord = cmd.ExecuteScalar().ToString();
AS Mackay
  • 2,831
  • 9
  • 19
  • 25
Profesor
  • 1
  • 3
-3

Use Stored Procedure only for the queries and use SCOPE_IDENTITY to get max value.

Pankaj
  • 9,749
  • 32
  • 139
  • 283
  • 3
    This is parameterised already. The `Parameters.AddWithValue` tells us this. – gbn May 24 '11 at 11:54
  • While writing the queries and sending to network can produce congestion. Like OP wrote "string query = "INSERT INTO SocialGroup (created_by_fbuid) VALUES (@FBUID); SELECT @@IDENTITY AS LastID"; " This is not a good practice. This should be in stored procedure – Pankaj May 24 '11 at 11:57
  • 2
    do you have an authoritative reference to describe that behaviour? A stored proc call is still sent over the network too. – gbn May 24 '11 at 12:43
  • Thank you for 30 downvotes: you really shouldn't post in public if you can't deal with criiticsm. Note: your rep profile gives this downvoting away so don't deny it... FYI: http://meta.stackexchange.com/questions/28756 – gbn May 24 '11 at 13:18
-16
SqlCommand command = new SqlCommand("select max(id) from SocialGroup ", connection);
int lastId = (int)command.ExecuteScalar();
Arjan Einbu
  • 13,543
  • 2
  • 56
  • 59
maephisto
  • 4,952
  • 11
  • 53
  • 73
  • 2
    MAX(id) is probably not the right way. SCOPE_IDENTITY() as suggested elsewhere is better. – Arjan Einbu May 24 '11 at 11:36
  • 2
    -1 for possibly the worst answer I've seen to this common questions – gbn May 24 '11 at 11:39
  • 6
    -1 Also. Just in case you are unsure of the problem a concurrent transaction could perform an insert and thus your select returns the wrong result. – Martin Smith May 24 '11 at 11:56