当执行存储过程时,使用CommandType.StoredProcedure和使用CommandType.Text有什么好处? [英] When executing a stored procedure, what is the benefit of using CommandType.StoredProcedure versus using CommandType.Text?

查看:197
本文介绍了当执行存储过程时,使用CommandType.StoredProcedure和使用CommandType.Text有什么好处?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  string sql = GetClientDefaults; 

SqlCommand cmd = new SqlCommand(sql);
cmd.CommandType = CommandType.StoredProcedure; //< - 我需要吗?
cmd.Parameters.AddWithValue(@ computerName,computerName);

其中sql是存储过程的名称。现在,这段代码似乎工作很好,有和没有注释行。



那么,我需要这行吗?是否有一些性能(或其他)的好处设置这个?

解决方案

根据这篇博文 SQL Server将使用 CommandType.Text 将您的语句包装在sp_executesql中,为您执行参数化。但是当你使用 CommandType.StoredProcedure 时,你将参数化它,从而保存数据库一些工作。后一种方法更快。



编辑



/ strong>



我自己做了一些测试,这里是结果。



创建此过程:

  create procedure dbo.Test 

@ Text1 varchar(10)='Default1'
,@ Text2 varchar(10)='Default2'

as
begin
select @ Text1为Text1,@ Text2为Text2
end

使用SQL Server Profiler向其中添加跟踪。



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

 使用System; 
using System.Data;
使用System.Data.SqlClient;

命名空间ConsoleApplication2
{
类程序
{
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);
使用(IDataReader reader = textCommand.ExecuteReader())
{
while(reader.Read())
{
Console.WriteLine(reader [Text1 ] ++ reader [Text2]);
}
}
}
}
}
}
}

结果



在这两种情况下,都是使用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. 使用 CommandType.StoredProcedure 更快。

  2. 您使用 CommandType.Text ,则必须将参数名称添加到对过程的调用,除非您希望使用默认值。


So in C# to use a stored procedure I have code like the following (connection code omitted):

 string sql = "GetClientDefaults";

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

Where sql is the name of a stored procedure. Now, this code seems to work just fine with and without the commented line.

So, do I need this line? Is there some performance (or other) benefit to setting this? Is there a benefit to NOT setting it or setting it to Text?

解决方案

According to the tests in this blog post SQL Server will do the parameterization for you, by wrapping your statement in sp_executesql, when you use CommandType.Text. But when you use CommandType.StoredProcedure you will parameterize it and thereby saving the database some work. The latter method is faster.

Edit:

Setup

I've done some tests myself and here are the results.

Create this procedure:

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

Add a trace to it using SQL Server Profiler.

And then call it using the following code:

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

In both cases the calls are made using RPC.

Here's what the trace reveals using CommandType.Text:

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

And here is the result using CommandType.StoredProcedure:

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

As you can see the text-call is wrapped in a call to sp_executesql so that it is properly parameterized. This will of course create a slight overhead, and thus my previous statement that using CommandType.StoredProcedure is faster still stands.

Another noteworthy thing, and which is also kind of a deal breaker here, is that when I created the procedure without default values I got the following error:

Msg 201, Level 16, State 4, Procedure Test, Line 0 Procedure or function 'Test' expects parameter '@Text1', which was not supplied.

The reason for this is how the call to sp_executesql is created, as you can see the parameters are declared and initialized, but they are not used. For the call to work, it should have looked like this:

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

Meaning, when you're using CommandType.Text you have to add the parameters to the CommandText unless you always want the default values to be used.

So, to answer your question

  1. Using CommandType.StoredProcedure is faster.
  2. If you're using CommandType.Text, then you'll have to add the parameter names to the call to the procedure unless you want the default values to be used.

这篇关于当执行存储过程时,使用CommandType.StoredProcedure和使用CommandType.Text有什么好处?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆