如何使用单个SqlCommand插入记录并返回新创建的ID?

时间:2008-12-01 12:37:50

标签: c# sql sql-server

我正在使用SqlCommand对象将记录插入到具有自动生成主键的表中。当我使用ExecuteScalar()方法时,如何编写命令文本以便获取新创建的ID?

9 个答案:

答案 0 :(得分:74)

INSERT INTO YourTable(val1, val2, val3 ...) 
VALUES(@val1, @val2, @val3...);
SELECT SCOPE_IDENTITY();

不要忘记每个陈述末尾的分号。

答案 1 :(得分:25)

将以下行添加到Sql Query的末尾...

SELECT SCOPE_IDENTITY()

然后在SqlCommand对象上使用ExecuteScalar方法......

var rowCount = command.ExecuteScalar()

答案 2 :(得分:16)

insert into Yourtable()  
values()  
SELECT SCOPE_IDENTITY()

我刚刚运行了测试,并使用SQL Server 2005 SP2和.Net 3.5验证了分号是可选的

答案 3 :(得分:5)

将输出参数添加到命令对象,然后将值设置为存储过程中的新ID。

存储过程:

@ID AS INT OUTPUT

[Insert Command]

SET @ID = SCOPE_IDENTITY()

<强> .NET:

cmd.CommandText = "stored_procedure";

SqlParameter pID = new SqlParameter("ID", DBType.Int32, 4);

pID.Direction = ParameterDirection.Output;

cmd.ExecuteScalar();

int id = Convert.ToInt32(cmd.Parameters["ID"].Value.ToString());

答案 4 :(得分:2)

在插入stmt之后,立即使用

SELECT CAST(scope_identity() AS bigint) ---- incase you have a return result as int64

这将返回创建的id / identity列。

答案 5 :(得分:2)

不要使用@@ IDENTITY,但看起来很简单。它可以返回不正确的值。

SELECT SCOPE_IDENTITY()

似乎是明显的选择。

答案 6 :(得分:1)

直接离开Whirlpool

  

如果您正在使用MS SQL,则可以在插入后使用“SELECT @@ IDENTITY as Value”来获取最后生成的ID

  

@@IDENTITYSCOPE_IDENTITY返回当前会话中任何表中生成的最后一个标识值。但是,SCOPE_IDENTITY仅在当前范围内返回值; @@IDENTITY不限于特定范围。

修改:正如评论中所指出的,您应该始终使用SCOPE_IDENTITY,而不是@@IDENTITY

答案 7 :(得分:1)

虽然我喜欢Dave Markle's回答,(我也看到你也这样做了,因为你把它标记为你的答案),如果你的数据库有触发器,审计CUD操作和你的审计,那么这个方法可能会失败table有一个IDENTITY列。它将返回Audit表的标识值,而不是您刚刚插入的表,因为审计表实际上是在之后发生的。

在这种情况下,可以使用更通用的方法,无论是否进行任何审计,都可以在两种情况下使用。它有点罗嗦,但你得到你付出的代价。

示例:

@"DECLARE @tmp AS TABLE ( id int )
                    INSERT INTO case
                    (
                        caseID,
                        partID,
                        serialNumber,
                        hardware,
                        software,
                        firmware
                    )
                    OUTPUT Inserted.ID into @tmp
                    VALUES
                    (
                        @caseID,
                        @partItemID,
                        @serialNumber,
                        @hardware,
                        @software,
                        @firmware
                    )
                Select ID from @tmp" )

答案 8 :(得分:1)

如果你的身份证是Guid,那么我发现这个解决方案是最好的:

INSERT INTO YourTable (val1, val2, val3) 
OUTPUT inserted.id 
VALUES (@val1, @val2, @val3)

谢谢@Scott Ivey

完整演示:

    internal static Guid InsertNote(Note note)
    {
            Guid id;

            using (
                var connection =
                    new SqlConnection(ConfigurationManager.ConnectionStrings["dbconn"].ConnectionString))
            {
                connection.Open();
                using (
                    var command =
                        new SqlCommand(
                            "INSERT INTO Notes ([Title],[Text]) " +
                            "OUTPUT inserted.id " +
                            $"VALUES ('{title}','{text}');", connection))
                {
                    command.CommandType = CommandType.Text;
                    var reader = command.ExecuteReader();
                    reader.Read();
                    id = reader.GetGuid(reader.GetOrdinal("id"));
                }
                connection.Close();
            }

            return id;
    }

我建议使用存储过程,但这是用于单元测试我们的存储库。