Question

I am currently working in C#, and I need to insert a new record into one table, get the new primary key value, and then use that as a foreign key reference in inserting several more records. The Database is MS SQL Server 2003. All help is appreciated!

Was it helpful?

Solution

The way to get the identity of the inserted row is with the SCOPE_IDENTITY() function. If you're using stored procedures then this would look something like the following to return the row identity as an output parameter.

CREATE PROCEDURE dbo.MyProcedure
(
    @RowId INT = NULL OUTPUT
)
AS

INSERT INTO MyTable
(
    Column1
    ,Column2
    ,...
)
VALUES
(
    @Param1
    ,@Param2
    ,...
);

SET @RowId = SCOPE_IDENTITY();

You can then use this value for any subsequent inserts (alternatively, if you can pass the data all into the stored procedure, then you can use it in the remainder of the procedure body).

If you're passing the SQL in dynamically then you use much the same technique, but with a single string with statement delimiters (also ; in SQL), e.g.:

var sql = "INSERT INTO MyTable (Column1, Column2, ...) VALUES (@P1, @P2, ...);" +
          "SELECT SCOPE_IDENTITY();";

Then if you execute this using ExecuteScalar you'll be able to get the identity back as the scalar result and cast it to the right type. Alternatively you could build up the whole batch in one go, e.g.

var sql = "DECLARE @RowId INT;" + 
          "INSERT INTO MyTable (Column1, Column2, ...) VALUES (@P1, @P2, ...);" +
          "SET @RowId = SCOPE_IDENTITY();" +
          "INSERT INTO MyOtherTable (Column1, ...) VALUES (@P3, @P4, ...);";

This may not be exactly the right syntax, and you may need to use SET NOCOUNT ON; at the start (my mind is rusty as I rarely use dynamic SQL) but it should get you on the right track.

OTHER TIPS

The best way of doing this is the use SCOPE_IDENTITY() function in TSQL. This should be executed as part of the insert i.e.

SqlCommand cmd = new SqlCommand(@"
    INSERT INTO T (Name) VALUES(@Name)
    SELECT SCOPE_IDENTITY() As TheId", conn);
cmd.AddParameter("@Name", SqlDbType.VarChar, 50).Value = "Test";
int tId = (int)cmd.ExecuteScalar();

Alternatively you can assign SCOPE_IDENTITY() to a variable to be used in successive statements. e.g.

DECLARE @T1 int

INSERT INTO T (Name) VALUES('Test')

SELECT @T1 = SCOPE_IDENTITY() 

INSERT INTO T2 (Name, TId) VALUES('Test', @T1)

If you are just using SQL then check Duncan's answer. If however you are using LINQ then you can create the entity, save it to the DB and the ID parameter will be populated automatically.

Given a user entity and a user table it might look like this:

using(var db = new DataContext()) {
    var user = new User { Name = "Jhon" };
    db.Users.InsertOnSubmit(user);
    db.SubmitChanges();
    /* At this point the user.ID field will have the primary key from the database */
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top