sql >> Database >  >> RDS >> Sqlserver

Wat is bij het uitvoeren van een opgeslagen procedure het voordeel van het gebruik van CommandType.StoredProcedure versus het gebruik van CommandType.Text?

Volgens de tests in deze blogpost zal SQL Server de parametrering voor u doen, door uw instructie in sp_executesql in te pakken, wanneer u CommandType.Text gebruikt . Maar wanneer u CommandType.StoredProcedure . gebruikt je zult het parametriseren en daarmee de database wat werk besparen. De laatste methode is sneller.

Bewerken:

Instellen

Ik heb zelf wat tests gedaan en hier zijn de resultaten.

Maak deze procedure:

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

Voeg er een spoor aan toe met SQL Server Profiler.

En roep het dan aan met de volgende 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"]);
                        }
                    }
                }
            }
        }
    }
}

Resultaten

In beide gevallen worden de oproepen gedaan met RPC.

Dit is wat het spoor onthult met behulp van CommandType.Text :

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

En hier is het resultaat met behulp van CommandType.StoredProcedure :

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

Zoals je kunt zien, is de tekstoproep verpakt in een aanroep naar sp_executesql zodat het goed geparametriseerd is. Dit zal natuurlijk een lichte overhead veroorzaken, en dus mijn eerdere verklaring dat het gebruik van CommandType.StoredProcedure is sneller staat nog steeds.

Een ander opmerkelijk ding, en dat is ook een soort dealbreaker hier, is dat toen ik de procedure zonder standaardwaarden maakte, ik de volgende foutmelding kreeg:

Msg 201, Level 16, State 4, Procedure Test, Line 0 Procedure of function 'Test' verwacht parameter '@Text1', die niet is opgegeven.

De reden hiervoor is hoe de aanroep naar sp_executesql is gemaakt, zoals je kunt zien, zijn de parameters gedeclareerd en geïnitialiseerd, maar ze worden niet gebruikt . Om de oproep te laten werken, had het er als volgt uit moeten zien:

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

Dit betekent dat wanneer u CommandType.Text . gebruikt je moet de parameters toevoegen aan de CommandText tenzij u altijd wilt dat de standaardwaarden worden gebruikt.

Dus, om je vraag te beantwoorden

  1. Gebruik CommandType.StoredProcedure is sneller.
  2. Als u CommandType.Text gebruikt , dan moet u de parameternamen toevoegen aan de aanroep van de procedure, tenzij u wilt dat de standaardwaarden worden gebruikt.


  1. 4 manieren om overbelasting van waarschuwingen te voorkomen met SQL Server Monitoring

  2. Onderhoudstaken voor SQL-databases automatiseren met SQLCMD

  3. Hoe DATE_ADD() werkt in MariaDB

  4. SQL SERVER – Een truc om met dynamische SQL om te gaan om een ​​SQL-injectieaanval te voorkomen?