sql >> Database teknologi >  >> RDS >> Sqlserver

Når du udfører en lagret procedure, hvad er fordelen ved at bruge CommandType.StoredProcedure i forhold til at bruge CommandType.Text?

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

  1. Ved brug af CommandType.StoredProcedure er hurtigere.
  2. 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.


  1. PostgreSQL Connection Pooling:Del 3 – Pgpool-II

  2. Hvordan opsætter man pandas DataFrame til PostgreSQL-tabellen?

  3. Sådan implementeres PostgreSQL for høj tilgængelighed

  4. PDO-bindingsværdier for MySQL IN-sætning