4

我目前正在使用 C#,我需要在一个表中插入一条新记录,获取新的主键值,然后在插入更多记录时将其用作外键引用。数据库是 MS SQL Server 2003。感谢所有帮助!

4

3 回答 3

8

获取插入行标识的方法是使用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),但它应该让您走上正确的轨道。

于 2008-11-25T00:27:32.667 回答
4

最好的方法是在 TSQL 中使用 SCOPE_IDENTITY() 函数。这应该作为插入的一部分执行,即

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)
于 2008-11-25T00:24:44.590 回答
3

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 */
}
于 2008-11-25T00:31:20.893 回答