Ifølge testene i dette blogindlæg vil SQL Server udføre parametreringen for dig, ved at pakke din sætning ind i sp_executesql, når du bruger CommandType.Text
. Men når du bruger CommandType.StoredProcedure
du vil parametrisere den og derved spare databasen noget arbejde. Sidstnævnte metode er hurtigere.
Rediger:
Opsætning
Jeg har selv lavet nogle test, og her er resultaterne.
Opret denne procedure:
create procedure dbo.Test
(
@Text1 varchar(10) = 'Default1'
,@Text2 varchar(10) = 'Default2'
)
as
begin
select @Text1 as Text1, @Text2 as Text2
end
Tilføj et spor til det ved hjælp af SQL Server Profiler.
Og kald det derefter ved hjælp af følgende kode:
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"]);
}
}
}
}
}
}
}
Resultater
I begge tilfælde foretages opkaldene ved hjælp af RPC.
Her er, hvad sporet afslører ved hjælp af CommandType.Text
:
exec sp_executesql N'dbo.Test',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'
Og her er resultatet ved hjælp af CommandType.StoredProcedure
:
exec dbo.Test @Text1=N'Text1',@Text2=N'Text2'
Som du kan se, er tekstopkaldet pakket ind i et opkald til sp_executesql
så den er korrekt parametriseret. Dette vil naturligvis skabe en lille overhead, og dermed min tidligere udtalelse om, at brug af CommandType.StoredProcedure
er hurtigere, står stadig.
En anden bemærkelsesværdig ting, og som også er en slags deal breaker her, er, at da jeg oprettede proceduren uden standardværdier, fik jeg følgende fejl:
Meddelelse 201, Niveau 16, Tilstand 4, Proceduretest, Linje 0 Procedure eller funktion 'Test' forventer parameter '@Text1', som ikke blev leveret.
Årsagen til dette er, hvordan kaldet til sp_executesql
er oprettet, som du kan se, er parametrene erklæret og initialiseret, men de bruges ikke . For at opkaldet skulle virke, skulle det have set sådan ud:
exec sp_executesql N'dbo.Test @Text1, @Text2',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'
Det betyder, når du bruger CommandType.Text
du skal tilføje parametrene til CommandText
medmindre du altid ønsker, at standardværdierne skal bruges.
Så for at besvare dit spørgsmål
- Ved brug af
CommandType.StoredProcedure
er hurtigere. - Hvis du bruger
CommandType.Text
, så bliver du nødt til at tilføje parameternavnene til kaldet til proceduren, medmindre du ønsker, at standardværdierne skal bruges.