ExecuteScalar()返回null,尽管数据已添加到数据库。

7
我有以下代码,试图将数据插入表中并返回新元素的ID(由自动递增给出)。
int newEquipmentID = new int();

query = database.ParameterizedQueryString("INSERT INTO Equipment (EquipmentTypeID) VALUES ({0})", "equipmenttypeID");

newEquipmentID = (int)database.Connection.ExecuteScalar(query, DefaultTimeout, equipment.EquipmentTypeID);

但是它失败并返回null,就好像新项目还没有添加一样。但是实际上,通过对数据库进行简单的查询,我可以看到新项目已被添加。

我的问题是,“何时”数据实际上被添加到数据库中,以及如何获取新添加项目的ID。 谢谢!

4个回答

15

创建新记录并检索新的标识值不需要两个查询:

using (var con = new SqlConnection(ConnectionString)) {
    int newID;
    var cmd = "INSERT INTO foo (column_name)VALUES (@Value);SELECT CAST(scope_identity() AS int)";
    using (var insertCommand = new SqlCommand(cmd, con)) {
        insertCommand.Parameters.AddWithValue("@Value", "bar");
        con.Open();
        newID = (int)insertCommand.ExecuteScalar();
    }
}

顺便说一下:我不会使用这样的数据库类,因为容易出现错误


3

您的SQL查询未返回新生成的ID。要返回它,请使用OUTPUT子句

INSERT INTO Equipment (<list of fields>) 
    OUTPUT inserted.EquipmentTypeID 
VALUES (<list of values>)

需要注意的几点:

  • <字段列表> 表示你将提供值的逗号分隔列的列表
  • 字段列表不应该包括自增ID列(它将自动分配一个值)
  • <值列表>表示将插入上述指定字段中的逗号分隔值列表。值的数量应该等于字段的数量,并且数据类型必须匹配

2
为了返回刚插入行的ID,您需要选择它,因为ExecuteScalar()返回查询结果集中第一行的第一列。而INSERT不会选择/返回任何内容。请注意保留HTML标记。
insert ...
select ...

请参阅@Tim的答案以获取更多详细信息。

ExecuteScalar() 返回一个元素的第一个字段(顶部行左列元素)。 - Guilherme Campos
但我不想要受影响的行数,我想要新增行的ID。 - Guilherme Campos

0

使用 OUTPUT 子句可以帮助您获取新添加项的 ID。更多信息请参见下面的链接:

点击这里!以获取更多详细信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接