Megosztás a következőn keresztül:


sp_executesql (Transact-SQL)

A következőkre vonatkozik:SQL ServerAzure SQL DatabaseFelügyelt Azure SQL-példányAzure Synapse AnalyticsElemzési platformrendszer (PDW)SQL Analytics-végpont a Microsoft FabricbenRaktár a Microsoft FabricbenSQL-adatbázis a Microsoft Fabricben

Olyan Transact-SQL utasítást vagy köteget hajt végre, amely többször újra felhasználható, vagy dinamikusan készült. A Transact-SQL utasítás vagy köteg beágyazott paramétereket tartalmazhat.

Caution

A futtatókörnyezet által lefordított Transact-SQL utasítások kártékony támadásoknak tehetik elérhetővé az alkalmazásokat. A lekérdezéseket paramétereznie kell a sp_executesqlhasználatakor. További információ: SQL-injektálási.

Transact-SQL szintaxis konvenciói

Syntax

Az SQL Server, az Azure SQL Database, az Azure SQL Managed Instance, az Azure Synapse Analytics és az Analytics Platform System (PDW) szintaxisa.

sp_executesql [ @stmt = ] N'statement'
[
    [ , [ @params = ] N'@parameter_name data_type [ { OUT | OUTPUT } ] [ , ...n ]' ]
    [ , [ @param1 = ] 'value1' [ , ...n ] ]
]

A cikkben szereplő kódminták a AdventureWorks2025 vagy AdventureWorksDW2025 mintaadatbázist használják, amelyet a Microsoft SQL Server-minták és közösségi projektek kezdőlapjáról tölthet le.

Arguments

Important

A kiterjesztett tárolt eljárások argumentumait a Szintaxis szakaszban leírt sorrendben kell megadni. Ha a paraméterek sorrenden kívül vannak beírva, hibaüzenet jelenik meg.

[ @stmt = ] N'utasítás'

Unicode-sztring, amely Transact-SQL utasítást vagy köteget tartalmaz. @stmt Unicode-állandónak vagy Unicode-változónak kell lennie. Az összetettebb Unicode-kifejezések, például két sztring összefűzése az + operátorral nem engedélyezettek. A karakterállandók nem engedélyezettek. A Unicode-állandóknak előtaggal kell rendelkeznie egy N. A Unicode-állandó N'sp_who' például érvényes, de a 'sp_who' karakterállandó nem. A sztring méretét csak a rendelkezésre álló adatbázis-kiszolgálói memória korlátozza. 64 bites kiszolgálókon a sztring mérete legfeljebb 2 GB, a maximális mérete nvarchar(max).

@stmt tartalmazhat olyan paramétereket, amelyek űrlapja megegyezik a változó nevével. Például:

N'SELECT * FROM HumanResources.Employee WHERE EmployeeID = @IDParameter';

A @stmt minden paraméterének rendelkeznie kell egy megfelelő bejegyzéssel mind a @params paraméterdefiníciós listában, mind a paraméterértékek listájában.

[ @params = ] N'@parameter_namedata_type [ , ... n ]'

Egy sztring, amely a @stmtbeágyazott összes paraméter definícióját tartalmazza. A sztringnek Unicode-állandónak vagy Unicode-változónak kell lennie. Minden paraméterdefiníció egy paraméternévből és egy adattípusból áll. n egy helyőrző, amely több paraméterdefiníciót jelez. A @stmt megadott paramétereket @paramskell definiálni. Ha a @stmt Transact-SQL utasítása vagy kötege nem tartalmaz paramétereket, @params nem szükséges. A paraméter alapértelmezett értéke NULL.

[ @param1 = ] 'érték1'

A paramétersztringben definiált első paraméter értéke. Az érték lehet Unicode-állandó vagy Unicode-változó. A @stmtminden paraméteréhez meg kell adni egy paraméterértéket. Az értékekre nincs szükség, ha a @stmt Transact-SQL utasításának vagy kötegének nincsenek paraméterei.

{ KIFELÉ | KIMENET }

Azt jelzi, hogy a paraméter kimeneti paraméter. szöveges, és képi paraméterek használhatók OUTPUT paraméterekként, kivéve, ha az eljárás általános nyelvi futtatókörnyezeti (CLR-) eljárás. A OUTPUT kulcsszót használó kimeneti paraméter lehet kurzorhelyőrző, kivéve, ha az eljárás CLR-eljárás.

[ ... n ]

A további paraméterek értékeinek helyőrzője. Az értékek csak állandók vagy változók lehetnek. Az értékek nem lehetnek összetettebb kifejezések, például függvények vagy operátorok által létrehozott kifejezések.

Kódértékek visszaadása

0 (sikeres) vagy nem nulla (hiba).

Eredményhalmaz

Az eredményhalmazokat az SQL-sztringbe épített összes SQL-utasításból adja vissza.

Remarks

sp_executesql paramétereket a cikk korábbi, Szintaxis szakaszában leírt sorrendben kell megadni. Ha a paraméterek sorrenden kívül vannak beírva, hibaüzenet jelenik meg.

sp_executesql ugyanaz a viselkedése, mint EXECUTE a kötegek, a nevek hatóköre és az adatbázis-környezet tekintetében. A sp_executesql@stmt paraméter Transact-SQL utasítása vagy kötege csak a sp_executesql utasítás végrehajtásáig lesz lefordítva. A @stmt tartalmát a rendszer a sp_executesqlnevű köteg végrehajtási tervétől eltérő végrehajtási tervként állítja össze és hajtja végre. A sp_executesql köteg nem hivatkozhat a sp_executesqlhívását kezdeményező kötegben deklarált változókra. A sp_executesql köteg helyi kurzorai vagy változói nem láthatók a sp_executesqlmeghívó köteg számára. Az adatbázis-környezet változásai csak a sp_executesql utasítás végéig tartanak.

sp_executesql használható tárolt eljárások helyett egy Transact-SQL utasítás többszöri végrehajtásához, amikor az egyetlen variáció a paraméterértékek módosítása az utasításra. Mivel maga a Transact-SQL utasítás állandó marad, és csak a paraméterértékek változnak, az SQL Server lekérdezésoptimalizálója valószínűleg újra felhasználja az első végrehajtáshoz létrehozott végrehajtási tervet. Ebben a forgatókönyvben a teljesítmény egyenértékű a tárolt eljárás teljesítményével.

Note

A teljesítmény javítása érdekében használjon teljes mértékben minősített objektumneveket az utasítási sztringben.

sp_executesql támogatja a paraméterértékek beállítását a Transact-SQL sztringtől elkülönítve, ahogyan az az alábbi példában is látható.

DECLARE @IntVariable AS INT;
DECLARE @SQLString AS NVARCHAR (500);
DECLARE @ParmDefinition AS NVARCHAR (500);

/* Build the SQL string once */
SET @SQLString = N'SELECT BusinessEntityID, NationalIDNumber, JobTitle, LoginID
       FROM AdventureWorks2022.HumanResources.Employee
       WHERE BusinessEntityID = @BusinessEntityID';

SET @ParmDefinition = N'@BusinessEntityID tinyint';

/* Execute the string with the first parameter value. */
SET @IntVariable = 197;

EXECUTE sp_executesql
    @SQLString,
    @ParmDefinition,
    @BusinessEntityID = @IntVariable;

/* Execute the same string with the second parameter value. */
SET @IntVariable = 109;

EXECUTE sp_executesql
    @SQLString,
    @ParmDefinition,
    @BusinessEntityID = @IntVariable;

A kimeneti paraméterek sp_executesqlis használhatók. Az alábbi példa lekéri a feladat címét a HumanResources.Employee mintaadatbázis AdventureWorks2025 táblájából, és visszaadja a @max_titlekimeneti paraméterben.

DECLARE @IntVariable AS INT;
DECLARE @SQLString AS NVARCHAR (500);
DECLARE @ParmDefinition AS NVARCHAR (500);
DECLARE @max_title AS VARCHAR (30);

SET @IntVariable = 197;

SET @SQLString = N'SELECT @max_titleOUT = max(JobTitle)
   FROM AdventureWorks2022.HumanResources.Employee
   WHERE BusinessEntityID = @level';

SET @ParmDefinition = N'@level TINYINT, @max_titleOUT VARCHAR(30) OUTPUT';

EXECUTE sp_executesql
    @SQLString,
    @ParmDefinition,
    @level = @IntVariable,
    @max_titleOUT = @max_title OUTPUT;

SELECT @max_title;

A paraméterek sp_executesql való helyettesítése a következő előnyöket nyújtja a EXECUTE utasítással egy sztring végrehajtásához:

  • Mivel a sp_executesql sztringben szereplő Transact-SQL utasítás tényleges szövege nem változik a végrehajtások között, a lekérdezésoptimalizáló valószínűleg megfelel az Transact-SQL utasításnak a második végrehajtásban az első végrehajtáshoz létrehozott végrehajtási tervvel. Ezért az SQL Servernek nem kell lefordítani a második utasítást.

  • A Transact-SQL sztring csak egyszer van létrehozva.

  • Az egész szám paraméter natív formátumban van megadva. A Unicode-ra való öntés nem kötelező.

OPTIMIZED_SP_EXECUTESQL

Vonatkozik a következőkre: SQL Server 2025 (17.x), Azure SQL Database és SQL database in Microsoft Fabric

Ha engedélyezve van a OPTIMIZED_SP_EXECUTESQL adatbázis hatókörű konfigurációs, a sp_executesql használatával elküldött kötegek fordítási viselkedése azonos lesz az objektumok, például a tárolt eljárások és az eseményindítók által jelenleg alkalmazott szerializált fordítási viselkedéssel.

Ha a kötegek azonosak (a paraméterkülönbségek kivételével), a OPTIMIZED_SP_EXECUTESQL lehetőség kényszerítési mechanizmusként próbál fordítási zárolást beszerezni, hogy a fordítási folyamat szerializálva legyen. Ez a zárolás biztosítja, hogy ha egyszerre több munkamenet is meghívja sp_executesql, ezek a munkamenetek várni fognak, miközben megpróbálják beszerezni a kizárólagos fordítási zárolást, miután az első munkamenet megkezdte a fordítási folyamatot. A sp_executesql első végrehajtása lefordítja és beszúrja a lefordított tervet a tervgyorsítótárba. A többi munkamenet megszakítja a fordítási zárolásra való várakozást, és amint elérhetővé válik, újra felhasználja a csomagot.

A OPTIMIZED_SP_EXECUTESQL lehetőség nélkül a sp_executesql párhuzamos fordítással végrehajtott azonos kötegek többszöri meghívása és a lefordított terv saját másolatainak elhelyezése a tervgyorsítótárba, amelyek bizonyos esetekben lecserélik vagy duplikálják a tervgyorsítótár bejegyzéseit.

Note

Mielőtt engedélyezi az OPTIMIZED_SP_EXECUTESQL adatbázis hatókörébe tartozó konfigurációt, ha az automatikus frissítési statisztikák engedélyezve van, engedélyeznie kell a automatikus frissítési statisztikák aszinkron beállítását is, az ASYNC_STATS_UPDATE_WAIT_AT_LOW_PRIORITY adatbázis-hatókörű konfigurációs beállítással. A két lehetőség engedélyezése jelentősen csökkentheti annak a valószínűségét, hogy a hosszú fordítási időhöz kapcsolódó teljesítményproblémák, valamint a túlzott, a zároláskezelő kizárólagos zárolásai (LCK_M_X) és a WAIT_ON_SYNC_STATISTICS_REFRESH várakozások.

OPTIMIZED_SP_EXECUTESQL alapértelmezés szerint ki van kapcsolva. A OPTIMIZED_SP_EXECUTESQL adatbázisszinten való engedélyezéséhez használja a következő Transact-SQL utasítást:

ALTER DATABASE SCOPED CONFIGURATION SET OPTIMIZED_SP_EXECUTESQL = ON;

Permissions

A nyilvános szerepkör tagságát igényli.

Examples

A. SELECT utasítás végrehajtása

Az alábbi példa létrehoz és végrehajt egy SELECT utasítást, amely egy @levelnevű beágyazott paramétert tartalmaz.

EXECUTE sp_executesql N'SELECT * FROM AdventureWorks2022.HumanResources.Employee
    WHERE BusinessEntityID = @level', N'@level TINYINT', @level = 109;

B. Dinamikusan összeállított sztring végrehajtása

Az alábbi példa egy dinamikusan összeállított sztring sp_executesql használatával szemlélteti. A példa tárolt eljárás használatával adatokat szúrhat be olyan táblákba, amelyek az értékesítési adatok egy évre történő particionálására szolgálnak. Az év minden hónapjára egy tábla van, amelynek formátuma a következő:

CREATE TABLE May1998Sales
(
    OrderID INT PRIMARY KEY,
    CustomerID INT NOT NULL,
    OrderDate DATETIME NULL CHECK (DATEPART(yy, OrderDate) = 1998),
    OrderMonth INT CHECK (OrderMonth = 5),
    DeliveryDate DATETIME NULL,
    CHECK (DATEPART(mm, OrderDate) = OrderMonth)
);

Ez a minta tárolt eljárás dinamikusan létrehozza és végrehajtja a INSERT utasítást, hogy új rendeléseket szúrjon be a megfelelő táblába. A példa a rendelés dátumát használja annak a táblának a nevére, amely tartalmaznia kell az adatokat, majd ezt a nevet egy INSERT utasításba foglalja.

Note

Ez egy egyszerű példa a sp_executesql. A példa nem tartalmaz hibaellenőrzést, és nem tartalmazza az üzleti szabályok ellenőrzését, például annak garantálását, hogy a rendelésszámok ne ismétlődjenek a táblák között.

CREATE PROCEDURE InsertSales (
    @PrmOrderID INT,
    @PrmCustomerID INT,
    @PrmOrderDate DATETIME,
    @PrmDeliveryDate DATETIME
)
AS
DECLARE @InsertString AS NVARCHAR (500);
DECLARE @OrderMonth AS INT;
-- Build the INSERT statement.
SET @InsertString = 'INSERT INTO ' +
    /* Build the name of the table. */
    SUBSTRING(DATENAME(mm, @PrmOrderDate), 1, 3)
    + CAST (DATEPART(yy, @PrmOrderDate) AS CHAR (4)) + 'Sales' +
    /* Build a VALUES clause. */
    ' VALUES (@InsOrderID, @InsCustID, @InsOrdDate,'
    + ' @InsOrdMonth, @InsDelDate)';

/* Set the value to use for the order month because
   functions are not allowed in the sp_executesql parameter
   list. */
SET @OrderMonth = DATEPART(mm, @PrmOrderDate);
EXECUTE sp_executesql
    @InsertString, N'@InsOrderID INT, @InsCustID INT, @InsOrdDate DATETIME, @InsOrdMonth INT, @InsDelDate DATETIME',
    @PrmOrderID,
    @PrmCustomerID,
    @PrmOrderDate,
    @OrderMonth,
    @PrmDeliveryDate;
GO

A sp_executesql használata ebben az eljárásban hatékonyabb, mint EXECUTE használata a dinamikusan összeállított sztring végrehajtásához, mivel lehetővé teszi a paraméterjelölők használatát. A paraméterjelölők valószínűbbé teszik, hogy az adatbázismotor újra felhasználja a létrehozott lekérdezési tervet, ami segít elkerülni a további lekérdezés-fordításokat. A EXECUTEesetében minden INSERT sztring egyedi, mert a paraméterértékek eltérőek, és a dinamikusan létrehozott sztring végéhez lesznek hozzáfűzve. A végrehajtáskor a lekérdezés nem paraméterezhető olyan módon, amely ösztönzi a terv újrafelhasználását, és minden egyes INSERT utasítás végrehajtása előtt össze kell állítani, ami külön gyorsítótárazott bejegyzést adna hozzá a lekérdezéshez a terv-gyorsítótárban.

C. A OUTPUT paraméter használata

Az alábbi példa egy OUTPUT paramétert használ a SELECT utasítás által létrehozott eredményhalmaz tárolására a @SQLString paraméterben. Ezután két SELECT utasítás lesz végrehajtva, amelyek a OUTPUT paraméter értékét használják.

USE AdventureWorks2022;
GO

DECLARE @SQLString AS NVARCHAR (500);
DECLARE @ParmDefinition AS NVARCHAR (500);
DECLARE @SalesOrderNumber AS NVARCHAR (25);
DECLARE @IntVariable AS INT;

SET @SQLString = N'SELECT @SalesOrderOUT = MAX(SalesOrderNumber)
    FROM Sales.SalesOrderHeader
    WHERE CustomerID = @CustomerID';

SET @ParmDefinition = N'@CustomerID INT,
    @SalesOrderOUT NVARCHAR(25) OUTPUT';

SET @IntVariable = 22276;

EXECUTE sp_executesql
    @SQLString,
    @ParmDefinition,
    @CustomerID = @IntVariable,
    @SalesOrderOUT = @SalesOrderNumber OUTPUT;

-- This SELECT statement returns the value of the OUTPUT parameter.
SELECT @SalesOrderNumber;

-- This SELECT statement uses the value of the OUTPUT parameter in
-- the WHERE clause.
SELECT OrderDate,
       TotalDue
FROM Sales.SalesOrderHeader
WHERE SalesOrderNumber = @SalesOrderNumber;

Példák: Azure Synapse Analytics and Analytics Platform System (PDW)

D. SELECT utasítás végrehajtása

Az alábbi példa létrehoz és végrehajt egy SELECT utasítást, amely egy @levelnevű beágyazott paramétert tartalmaz.

EXECUTE sp_executesql
    N'SELECT * FROM AdventureWorksPDW2012.dbo.DimEmployee WHERE EmployeeKey = @level',
    N'@level TINYINT;',
    @level = 109;