在INSERT时返回ID

本文关键字:ID 返回 INSERT | 更新日期: 2023-09-27 17:54:59

我有一个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();

我现在有这个,我不确定下一步我需要做什么…

在INSERT时返回ID

您只需要将@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);

自SQL Server 2008以来,TSQL语法中添加了OUTPUT子句。这允许您将受DML查询影响的数据添加到表格数据流中。

虽然在查询后查询SCOPE_IDENTITY()返回正确的信息,但它强制SQL Server执行2个查询,而output子句将此限制为1个查询。

知道了这一点,执行的查询可以按如下方式修改(假设[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();
        }

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

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

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

将此添加到您的参数

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

执行后可以检索id

int id = (int)IDParameter.Value;

为什么不调用存储过程呢?将值传递给存储过程以获得插入的值,并从SP返回使用SCOPE_IDENTITY().插入的最后一个种子值。