C# 从MS SQL Server获取自动编号主键
我目前在C#中工作,需要在一个表中插入一条新记录,获取新的主键值,然后在插入多条记录时将其用作外键引用。数据库是MS SQL Server 2003。感谢您的帮助 最好的方法是在TSQL中使用SCOPE_IDENTITY()函数。这应作为插入的一部分执行,即C# 从MS SQL Server获取自动编号主键,c#,sql-server,autonumber,C#,Sql Server,Autonumber,我目前在C#中工作,需要在一个表中插入一条新记录,获取新的主键值,然后在插入多条记录时将其用作外键引用。数据库是MS SQL Server 2003。感谢您的帮助 最好的方法是在TSQL中使用SCOPE_IDENTITY()函数。这应作为插入的一部分执行,即 SqlCommand cmd = new SqlCommand(@" INSERT INTO T (Name) VALUES(@Name) SELECT SCOPE_IDENTITY() As TheId", conn);
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()指定给要在后续语句中使用的变量。e、 g
DECLARE @T1 int
INSERT INTO T (Name) VALUES('Test')
SELECT @T1 = SCOPE_IDENTITY()
INSERT INTO T2 (Name, TId) VALUES('Test', @T1)
获取插入行的标识的方法是使用
SCOPE\u identity()
函数。如果您使用的是存储过程,那么将行标识作为输出参数返回,如下所示
CREATE PROCEDURE dbo.MyProcedure
(
@RowId INT = NULL OUTPUT
)
AS
INSERT INTO MyTable
(
Column1
,Column2
,...
)
VALUES
(
@Param1
,@Param2
,...
);
SET @RowId = SCOPE_IDENTITY();
然后可以将此值用于任何后续插入(或者,如果可以将所有数据传递到存储过程中,则可以在过程体的其余部分中使用它)
如果要动态传入SQL,则使用大致相同的技术,但使用带有语句分隔符的单个字符串(在SQL中也是;
),例如:
然后,如果使用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),但这应该会让你走上正轨。如果你只是在使用SQL,那么请检查Duncan的答案。如果您使用LINQ,那么您可以创建实体,将其保存到DB,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 */
}
所有这些都是一个字符串,还是作为单独的字符串传入?你的解决方案不清楚这一点。记住,我是通过C#进行SQL查询的。在这两种情况下,都可以传递一个字符串。对于第一个方法,可以使用SqlCommand ExecuteScaler()获取刚刚插入的行的标识。您还需要使用command.AddParameter将硬编码的“Test”绑定到@Name参数,以避免sql注入。与返回数据集相比,我更喜欢这种方法(使用OUT参数)。特别是对于自动生成的代码。您可以通过调用.ExecuteScalar()跳过数据集。我更喜欢输出参数,因为我认为它们比标量结果集更具有自文档性,但任何一种方法都可以。您是使用像LINQ这样的框架还是使用SQL字符串查询?(在我的回答中,我假设是LINQ)这是LINQ到sql、LINQ到实体或dbcontext。以防有人意识到。。。
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 */
}