2011-05-06 56 views
22

我有一个INSERT查询,我希望数据库返回我刚刚插入的行的ID。INSERT返回ID?

sqlString = "INSERT INTO MagicBoxes (OwnerID, Key, Name, Permissions, Active, LastUpdated) VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) SET @ID = SCOPE_IDENTITY();"; 
cmd = new SqlCommand(sqlString, con); 
cmd.Parameters.AddWithValue("@OwnerID", OwnerID); 
cmd.Parameters.AddWithValue("@BoxKey", BoxKey); 
cmd.Parameters.AddWithValue("@BoxName", BoxName); 
cmd.Parameters.AddWithValue("@Username", Username); 
cmd.Parameters.AddWithValue("@Date", DateTime.Now); 
cmd.ExecuteNonQuery(); 

目前,我有这个,我不知道我下一步需要做...

+0

不能让你的问题,你要行的种子值刚插入? – 2011-05-06 11:01:39

回答

31

你只需要@ID添加到PARAMS集合,然后检索它这个样子,

cmd.Parameters.Add("@ID", SqlDbType.Int, 4).Direction = ParameterDirection.Output; 
cmd.ExecuteNonQuery(); 
//Now just read the value of: cmd.Parameters["@ID"].value 

或者,如果你喜欢这样的语法:

SqlParameter param = new SqlParameter("@ID", SqlDbType.Int, 4); 
param.Direction = ParameterDirection.Output; 
cmd.Parameters.Add(param); 
+0

'参数4:无法从'System.Data.ParameterDirection'转换为'string'' – Danpe 2011-05-06 11:04:12

+0

@Danpe = apologies,以上纠正 - 我总是发现增加输出参数比它需要更笨重 – AdaTheDev 2011-05-06 11:15:41

+2

我不能做这项工作,在执行命令后参数为空。这里的另一个答案使用ExecuteScalar,似乎产生了正确的值。具有存储过程的 – 2013-12-31 03:29:51

20

你有两个选择;您可以声明Output参数,称为@ID;或者 - 你可以结束更改为SELECT SCOPE_IDENTITY(),只需使用:

int id = (int)cmd.ExecuteScalar(); 

我喜欢的形式参数的方法,但ExecuteScalar效果很好。

3

这为您的参数

SqlParameter IDParameter = new SqlParameter("@ID",SqlDbType.Int); 
IDParameter.Direction = ParameterDirection.Output; 
cmd.Parameters.Add(IDParameter); 

添加执行可以检索ID

int id = (int)IDParameter.Value; 
0

你为什么不调用存储过程后。将值传递给存储过程以获取插入的值并从SP返回使用SCOPE_IDENTITY().插入的最后一个种子值希望得到此帮助。

+0

不会改变任何内容;这是关于参数/结果传递,这将是相同的 – 2011-05-06 11:32:25

+0

是的,你是对的,我的意思是说,调用SP并从SP返回插入后的最后一个种子值。 – 2011-05-06 11:35:13

12

由于SQL Server 2008中有一个OUTPUT clause添加到TSQL的语法。这使您可以将受DML查询影响的数据添加到表格数据流中。

尽管在查询返回正确的信息后查询SCOPE_IDENTITY(),它强制SQL Server执行2个查询,其中输出子句将其限制为一个查询。

知道了这一点,正在执行的查询可以改变如下(假设[Id]是标识的名称):

INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated) 
OUTPUT INSERTED.Id 
VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) 

的另一个问题是无法处置的SqlCommand的。 ADO.net中的大多数Sql...对象实现了IDisposable,应该妥善处理。

带来一切融合在一起我会实现如下这段代码:

 using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["db"].ConnectionString)) 
     using (var cmd = new SqlCommand(@" 
       INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated) 
       OUTPUT INSERTED.Id 
       VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) ", conn)) 
     { 
      cmd.Parameters.AddRange(new[] 
       { 
        new SqlParameter("@OwnerID", SqlDbType.Int).Value = OwnerID, 
        new SqlParameter("@BoxKey", SqlDbType.VarChar).Value = BoxKey, 
        new SqlParameter("@BoxName", SqlDbType.VarChar).Value = BoxName, 
        new SqlParameter("@Date", SqlDbType.DateTime).Value = DateTime.Now 
       }); 

      conn.Open(); 

      var id = (int)cmd.ExecuteScalar(); 
     } 
+1

这是最好的答案。 – 2018-01-24 18:26:56