执行存储过程时,使用 CommandType.StoredProcedure 与使用 CommandType.Text 相比有什么好处?

2024-01-02

因此,在 C# 中使用存储过程我有如下代码(连接代码省略):

 string sql = "GetClientDefaults";

 SqlCommand cmd = new SqlCommand(sql);
 cmd.CommandType = CommandType.StoredProcedure;    //<-- DO I NEED THIS??
 cmd.Parameters.AddWithValue("@computerName", computerName);

其中 sql 是存储过程的名称。现在,无论有没有注释行,这段代码似乎都可以正常工作。

那么,我需要这条线吗?设置此值是否有一些性能(或其他)好处?不设置它或将其设置为文本有好处吗?


根据测试这篇博文 http://sqlblog.com/blogs/tibor_karaszi/archive/2010/01/11/is-there-and-overhead-to-rpc-events.aspx当您使用时,SQL Server 将通过将语句包装在 sp_executesql 中来为您进行参数化CommandType.Text。但是当你使用CommandType.StoredProcedure您将对其进行参数化,从而节省数据库的一些工作。后一种方法更快。

Edit:

Setup

我自己做了一些测试,结果如下。

创建此过程:

create procedure dbo.Test
(
   @Text1 varchar(10) = 'Default1'
  ,@Text2 varchar(10) = 'Default2'
)
as
begin
   select @Text1 as Text1, @Text2 as Text2
end

使用 SQL Server Profiler 添加跟踪。

然后使用以下代码调用它:

using System;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main()
        {
            CallProcedure( CommandType.Text );
            CallProcedure( CommandType.StoredProcedure );
        }

        private static void CallProcedure(CommandType commandType)
        {
            using ( SqlConnection connection = new SqlConnection("Data Source=localhost;Initial Catalog=Test;Integrated Security=SSPI;") )
            {
                connection.Open();
                using ( SqlCommand textCommand = new SqlCommand("dbo.Test", connection) )
                {
                    textCommand.CommandType = commandType;
                    textCommand.Parameters.AddWithValue("@Text1", "Text1");
                    textCommand.Parameters.AddWithValue("@Text2", "Text2");
                    using ( IDataReader reader = textCommand.ExecuteReader() )
                    {
                        while ( reader.Read() )
                        {
                            Console.WriteLine(reader["Text1"] + " " + reader["Text2"]);
                        }
                    }
                }
            }
        }
    }
}

Results

在这两种情况下,调用都是使用 RPC 进行的。

这是跟踪揭示的内容CommandType.Text:

exec sp_executesql N'dbo.Test',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'

这是使用的结果CommandType.StoredProcedure:

exec dbo.Test @Text1=N'Text1',@Text2=N'Text2'

正如您所看到的,文本调用包含在对sp_executesql以便对其进行正确的参数化。这当然会产生轻微的开销,因此我之前的声明是使用CommandType.StoredProcedure更快仍然成立。

另一个值得注意的事情,也是这里的一个交易破坏者,是当我创建没有默认值的过程时,我收到以下错误:

消息 201,级别 16,状态 4,程序测试,第 0 行程序或 函数“Test”需要参数“@Text1”,但未提供该参数。

其原因是如何调用sp_executesql创建完毕,可以看到参数已声明并初始化,但他们没有被使用。对于正常工作的调用,它应该如下所示:

exec sp_executesql N'dbo.Test @Text1, @Text2',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'

意思是,当你使用CommandType.Text你必须将参数添加到CommandText除非您总是希望使用默认值。

所以,回答你的问题

  1. Using CommandType.StoredProcedure是比较快的。
  2. 如果您正在使用CommandType.Text,那么您必须将参数名称添加到对过程的调用中,除非您希望使用默认值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

执行存储过程时,使用 CommandType.StoredProcedure 与使用 CommandType.Text 相比有什么好处? 的相关文章

随机推荐