本文介绍了的ExecuteScalar VS的ExecuteNonQuery返回一个标识值时,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图找出是否最好使用的ExecuteScalar 的ExecuteNonQuery 如果我想返回的标识列新插入的行。我已阅读并我理解的差异存在,但找了一些代码,当我写了几个星期前(同时从本网站大量举债),我发现,在我插入我使用的ExecuteScalar ,像这样:



公共静态INT SaveTest(测试newTest)
{
变种康恩= DbConnect.Connection();
常量字符串的SqlString =INSERT INTO dbo.Tests(测试仪,前提)+
VALUES(@tester,@premise)​​+
SET @newId = SCOPE_IDENTITY(); ;
使用(康涅狄格州)
{
使用(VAR CMD =新的SqlCommand(的SqlString,康涅狄格州))
{
cmd.Parameters.AddWithValue(@测试仪, newTest.tester);
cmd.Parameters.AddWithValue(@前提,newTest.premise);
cmd.Parameters.Add(@ NEWID,SqlDbType.Int).Direction = ParameterDirection.Output;

cmd.CommandType = CommandType.Text;
conn.Open();
cmd.ExecuteScalar();

回报(INT)cmd.Parameters [@ NEWID]值。
}
}
}

这正常工作对我需要的,所以我不知道




  1. 我是否应该使用的ExecuteNonQuery 这里,因为它是更恰当做插入?

  2. 会检索标识值是相同无论哪种方式,因为我使用的是输出参数?

  3. 是否有一个方式或其他相关的任何性能命中?

  4. 有一般

    我使用Visual更好的方式来做到这一点的整体?




Studio 2010中,.NET 4.0和SQL Server 2008R2,万一有什么差别。


解决方案

正如亚伦建议因为它节省了Sql Server的编译SQL批处理的工作存储过程将使它更快。但是,你仍然可以去用两种方法:的ExecuteScalar 的ExecuteNonQuery 。 IMHO,它们之间的性能差异是如此之小,即任一方法只为合适。



话虽如此,我没有看到使用的点的ExecuteScalar 如果你抓住从标识值输出参数。在这种情况下,由的ExecuteScalar 返回的值变得无用。



这是我喜欢的,因为它需要较少的代码,使用一个方法的ExecuteScalar 无输出参数:

 公共静态INT SaveTest(测试newTest)
{
VAR康恩= DbConnect.Connection();
常量字符串的SqlString =INSERT INTO dbo.Tests(测试仪,前提)+
VALUES(@tester,@premise)​​+
SELECT SCOPE_IDENTITY();
使用(康涅狄格州)
{
使用(VAR CMD =新的SqlCommand(的SqlString,康涅狄格州))
{
cmd.Parameters.AddWithValue(@测试仪, newTest.tester);
cmd.Parameters.AddWithValue(@前提,newTest.premise);

cmd.CommandType = CommandType.Text;
conn.Open();
回报(INT)(十进制)cmd.ExecuteScalar();

}
}
}



快乐编程!



修改:请注意,我们需要转换两次:从对象到小数 ,然后到 INT (感谢techturtle的注意这一点)。


Trying to figure out if it's best to use ExecuteScalar or ExecuteNonQuery if I want to return the identity column of a newly inserted row. I have read this question and I understand the differences there, but when looking over some code I wrote a few weeks ago (whilst heavily borrowing from this site) I found that in my inserts I was using ExecuteScalar, like so:

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;
        }
    }
}

This works fine for what I need, so I'm wondering

  1. Whether I should be using ExecuteNonQuery here because it is "more proper" for doing inserts?
  2. Would retrieving the identity value be the same either way since I'm using an output parameter?
  3. Are there any performance hits associated with one way or the other?
  4. Is there generally a better way to do this overall?

I'm using Visual Studio 2010, .NET 4.0, and SQL Server 2008r2, in case that makes any difference.

解决方案

As suggested by Aaron, a stored procedure would make it faster because it saves Sql Server the work of compiling your SQL batch. However, you could still go with either approach: ExecuteScalar or ExecuteNonQuery. IMHO, the performance difference between them is so small, that either method is just as "proper".

Having said that, I don't see the point of using ExecuteScalar if you are grabbing the identity value from an output parameter. In that case, the value returned by ExecuteScalar becomes useless.

An approach that I like because it requires less code, uses ExecuteScalar without output parameters:

public static int SaveTest(Test newTest)
{
    var conn = DbConnect.Connection();
    const string sqlString = "INSERT INTO dbo.Tests ( Tester , Premise ) " +
                             "               VALUES ( @tester , @premise ) " +
                             "SELECT SCOPE_IDENTITY()";
    using (conn)
    {
        using (var cmd = new SqlCommand(sqlString, conn))
        {
            cmd.Parameters.AddWithValue("@tester", newTest.tester);
            cmd.Parameters.AddWithValue("@premise", newTest.premise);

            cmd.CommandType = CommandType.Text;
            conn.Open();
            return (int) (decimal) cmd.ExecuteScalar();

        }
    }
}

Happy programming!

EDIT: Note that we need to cast twice: from object to decimal, and then to int (thanks to techturtle for noting this).

这篇关于的ExecuteScalar VS的ExecuteNonQuery返回一个标识值时,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 18:29