【发布时间】:2012-12-24 04:20:02
【问题描述】:
如果我想返回新插入的行的标识列,则尝试确定最好使用ExecuteScalar 或ExecuteNonQuery。我已经阅读了this question 并且我理解那里的差异,但是在查看我几周前编写的一些代码时(同时大量从这个站点借用)我发现在我的插入中我使用了ExecuteScalar,就像这样:
public static int SaveTest(Test newTest)
{
var conn = DbConnect.Connection();
const string sqlString = "INSERT INTO dbo.Tests ( Tester , Premise ) " +
" VALUES ( @tester , @premise ) " +
"SET @newId = SCOPE_IDENTITY(); ";
using (conn)
{
using (var cmd = new SqlCommand(sqlString, conn))
{
cmd.Parameters.AddWithValue("@tester", newTest.tester);
cmd.Parameters.AddWithValue("@premise", newTest.premise);
cmd.Parameters.Add("@newId", SqlDbType.Int).Direction = ParameterDirection.Output;
cmd.CommandType = CommandType.Text;
conn.Open();
cmd.ExecuteScalar();
return (int) cmd.Parameters["@newId"].Value;
}
}
}
这可以满足我的需要,所以我想知道
- 我是否应该在这里使用
ExecuteNonQuery,因为它“更适合”进行插入? - 由于我使用的是输出参数,因此检索标识值是否相同?
- 是否存在与一种或另一种方式相关的性能影响?
- 总体上是否有更好的方法来做到这一点?
我正在使用 Visual Studio 2010、.NET 4.0 和 SQL Server 2008r2,以防万一。
【问题讨论】:
-
(1) 为什么
ExecuteNonQuery“更合适”? (2) 你考虑过使用存储过程吗?如果不是,为什么不呢?它肯定会帮助清理您放入应用程序的所有临时 SQL - 当您必须更改它时,这意味着您必须重新编译和重新部署应用程序。 -
嗯... ExecuteNonQuery 通常用于执行不期望返回结果的 SQL。 ExecuteScalar 返回一个值,因此您不需要传递参数。您可以将 SQL 的最后一部分更改为
SELECT SCOPE_IDENTITY();然后使用return (int)cmd.ExecuteScalar(); -
我使用
ExecuteScalar因为我使用SELECT SCOPE_IDENTITY没有输出参数,因此检索单个值这是ExecuteScalar的目的。 stackoverflow.com/a/9319609/284240 -
要记住的重要一点是应用程序的结构、目标和最简单的方法。正如 Aaron 所说,您可以采用存储过程路线;您甚至可以利用大型查询来提取数据并在代码中编译它们。这是一个偏好问题。但 Sam 对于“一般”目的是正确的。
-
@TimSchmelter 做到了。我永远不会猜到整个
numeric的事情,尤其是因为我的身份列是int(并且它在输出参数上没有强制转换)。我什至去找了reason why。
标签: c# sql-server executenonquery executescalar