Получение первичного ключа автонумерации из MS SQL Server - PullRequest
4 голосов
/ 25 ноября 2008

Я сейчас работаю в C #, и мне нужно вставить новую запись в одну таблицу, получить новое значение первичного ключа, а затем использовать его в качестве ссылки на внешний ключ при вставке еще нескольких записей. База данных MS SQL Server 2003. Любая помощь приветствуется!

Ответы [ 3 ]

8 голосов
/ 25 ноября 2008

Способ получения идентификатора вставленной строки - с помощью функции SCOPE_IDENTITY(). Если вы используете хранимые процедуры, то это будет выглядеть примерно так, чтобы вернуть идентификатор строки в качестве выходного параметра.

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

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

SET @RowId = SCOPE_IDENTITY();

Затем вы можете использовать это значение для любых последующих вставок (в качестве альтернативы, если вы можете передать все данные в хранимую процедуру, вы можете использовать ее в оставшейся части тела процедуры).

Если вы передаете SQL динамически, то вы используете почти такой же метод, но с одной строкой с разделителями операторов (также ; в SQL), например ::

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

Тогда, если вы выполните это с помощью ExecuteScalar, вы сможете получить идентичность обратно как скалярный результат и привести ее к нужному типу. В качестве альтернативы вы можете собрать всю партию за один раз, например

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

Это может быть не точно правильный синтаксис, и вам, возможно, придется использовать SET NOCOUNT ON; в начале (мой взгляд ржавый, поскольку я редко использую динамический SQL), но это должно помочь вам правильно трек.

4 голосов
/ 25 ноября 2008

Лучший способ сделать это - использовать функцию SCOPE_IDENTITY () в TSQL. Это должно быть выполнено как часть вставки, т.е.

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

В качестве альтернативы вы можете назначить SCOPE_IDENTITY () для переменной, которая будет использоваться в последующих инструкциях. например,

DECLARE @T1 int

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

SELECT @T1 = SCOPE_IDENTITY() 

INSERT INTO T2 (Name, TId) VALUES('Test', @T1)
3 голосов
/ 25 ноября 2008

Если вы используете только SQL, проверьте ответ Дункана. Однако, если вы используете LINQ, вы можете создать объект, сохранить его в БД, и параметр ID будет заполнен автоматически.

С учетом сущности пользователя и пользовательской таблицы это может выглядеть так:

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 */
}
...