我正在使用SqlCommand对象将记录插入到具有自动生成主键的表中。当我使用ExecuteScalar()方法时,如何编写命令文本以便获取新创建的ID?
答案 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
和
@@IDENTITY
和SCOPE_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;
}
我建议使用存储过程,但这是用于单元测试我们的存储库。