Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Şunlar için geçerlidir:SQL Server
Azure SQL Veritabanı
Azure SQL Yönetilen Örneği
Azure Synapse Analytics
Analytics Platform Sistemi (PDW)
Microsoft Fabric
Warehouse'da SQL analiz uç noktası
Birçok kez yeniden kullanılabilecek bir Transact-SQL deyimini veya toplu işlemini ya da dinamik olarak oluşturulan bir deyimini yürütür. Transact-SQL deyimi veya toplu işlemi katıştırılmış parametreler içerebilir.
Dikkat
Çalışma zamanı derlenmiş Transact-SQL deyimleri uygulamaları kötü amaçlı saldırılara maruz bırakabiliyor.
sp_executesql
kullanırken sorgularınızı parametreleştirmelisiniz. Daha fazla bilgi için bkz. sql ekleme .
Transact-SQL söz dizimi kuralları
Sözdizimi
SQL Server, Azure SQL Veritabanı, Azure SQL Yönetilen Örneği, Azure Synapse Analytics ve Analytics Platform Sistemi (PDW) için söz dizimi.
sp_executesql [ @stmt = ] N'statement'
[
[ , [ @params = ] N'@parameter_name data_type [ { OUT | OUTPUT } ] [ , ...n ]' ]
[ , [ @param1 = ] 'value1' [ , ...n ] ]
]
Bu makaledeki kod örnekleri, AdventureWorks2022
giriş sayfasından indirebileceğiniz AdventureWorksDW2022
veya örnek veritabanını kullanır.
Bağımsız değişken
Önemli
Genişletilmiş saklı yordamlar için bağımsız değişkenler, Sözdizimi bölümünde açıklandığı gibi belirli bir sırada girilmelidir. Parametreler sıra dışı girilirse bir hata iletisi oluşur.
[ @stmt = ] N'deyimi'
Transact-SQL deyimi veya toplu işlemi içeren bir Unicode dizesi.
@stmt bir Unicode sabiti veya Unicode değişkeni olmalıdır. İki dizeyi +
işleciyle birleştirmek gibi daha karmaşık Unicode ifadelerine izin verilmez. Karakter sabitlerine izin verilmez. Unicode sabitlerine bir N
ön eki eklenmelidir. Örneğin, Unicode sabiti N'sp_who'
geçerlidir, ancak karakter sabiti 'sp_who'
geçerli değildir. Dizenin boyutu yalnızca kullanılabilir veritabanı sunucusu belleğiyle sınırlıdır. 64 bit sunucularda, dizenin boyutu 2 GB ile sınırlıdır; en büyük boyut nvarchar(max).
@stmt, değişken adıyla aynı forma sahip parametreler içerebilir. Mesela:
N'SELECT * FROM HumanResources.Employee WHERE EmployeeID = @IDParameter';
@stmt dahil edilen her parametrenin hem @params parametre tanımı listesinde hem de parametre değerleri listesinde karşılık gelen bir girdisi olmalıdır.
[ @params = ] N'@parameter_namedata_type [ , ... n ]'
@stmteklenmiş tüm parametrelerin tanımlarını içeren bir dize. Dize bir Unicode sabiti veya Unicode değişkeni olmalıdır. Her parametre tanımı bir parametre adından ve bir veri türünden oluşur.
n, daha fazla parametre tanımını gösteren bir yer tutucudur.
@stmt'de belirtilen her parametre @paramsiçinde tanımlanmalıdır.
@stmt'daki Transact-SQL deyimi veya toplu işlemi parametre içermiyorsa @params gerekli değildir. Bu parametrenin varsayılan değeri NULL
.
[ @param1 = ] 'value1'
Parametre dizesinde tanımlanan ilk parametre için bir değer. Değer bir Unicode sabiti veya Unicode değişkeni olabilir. @stmtdahil edilen her parametre için bir parametre değeri sağlanmalıdır. @stmt'daki Transact-SQL deyiminde veya toplu işte parametre olmadığında değerler gerekli değildir.
{ OUT | OUTPUT }
Parametresinin bir çıkış parametresi olduğunu gösterir.
metin, ntextve görüntü parametreleri, yordam ortak dil çalışma zamanı (CLR) yordamı olmadığı sürece OUTPUT
parametreleri olarak kullanılabilir.
OUTPUT
anahtar sözcüğünü kullanan bir çıkış parametresi, yordam bir CLR yordamı olmadığı sürece imleç yer tutucusu olabilir.
[ ... n ]
Ek parametrelerin değerleri için yer tutucu. Değerler yalnızca sabitler veya değişkenler olabilir. Değerler, işlevler gibi daha karmaşık ifadeler veya işleçler kullanılarak oluşturulan ifadeler olamaz.
Dönüş kodu değerleri
0
(başarı) veya sıfır olmayan (başarısızlık).
Sonuç kümesi
SQL dizesinde yerleşik olarak bulunan tüm SQL deyimlerinden sonuç kümelerini döndürür.
Açıklamalar
sp_executesql
parametreleri, bu makalenin önceki bölümlerindeki Sözdizimi bölümünde açıklandığı gibi belirli bir sırada girilmelidir. Parametreler sıra dışı girilirse bir hata iletisi oluşur.
sp_executesql
toplu işler, adların kapsamı ve veritabanı bağlamı ile ilgili EXECUTE
aynı davranışa sahiptir.
sp_executesql
deyimi yürütülene kadar sp_executesql
parametresindeki Transact-SQL deyimi veya toplu işlemi derlenmemiştir.
@stmt içeriği daha sonra derlenir ve sp_executesql
adlı toplu işlemin yürütme planından ayrı bir yürütme planı olarak yürütülür.
sp_executesql
toplu işlemi, sp_executesql
çağıran toplu işte bildirilen değişkenlere başvuramaz.
sp_executesql
toplu işlemindeki yerel imleçler veya değişkenler, sp_executesql
çağıran toplu iş tarafından görünmez. Veritabanı bağlamındaki değişiklikler yalnızca sp_executesql
deyiminin sonuna kadar sürer.
sp_executesql
, bir Transact-SQL deyimini birçok kez yürütmek için saklı yordamlar yerine, deyimdeki parametre değerlerindeki değişiklik tek varyasyon olduğunda kullanılabilir. Transact-SQL deyiminin kendisi sabit kaldığından ve yalnızca parametre değerleri değiştiğinden, SQL Server sorgu iyileştiricisinin ilk yürütme için oluşturduğu yürütme planını yeniden kullanma olasılığı yüksektir. Bu senaryoda performans, saklı yordamla eşdeğerdir.
Not
Performansı geliştirmek için deyim dizesinde tam nesne adlarını kullanın.
sp_executesql
, aşağıdaki örnekte gösterildiği gibi parametre değerlerinin Transact-SQL dizesinden ayrı olarak ayarlanmasını destekler.
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;
Çıkış parametreleri sp_executesql
ile de kullanılabilir. Aşağıdaki örnek, HumanResources.Employee
örnek veritabanındaki AdventureWorks2022
tablosundan bir iş başlığı alır ve bunu @max_title
çıkış parametresinde döndürür.
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;
sp_executesql
'da parametreleri değiştirebilmek, bir dize yürütmek için EXECUTE
deyimini kullanmaya göre aşağıdaki avantajları sunar:
sp_executesql
dizesindeki Transact-SQL deyiminin gerçek metni yürütmeler arasında değişmediğinden, sorgu iyileştiricisi büyük olasılıkla ikinci yürütmedeki Transact-SQL deyimini ilk yürütme için oluşturulan yürütme planıyla eşleştirir. Bu nedenle, SQL Server'ın ikinci deyimini derlemesi gerekmez.Transact-SQL dizesi yalnızca bir kez oluşturulur.
Tamsayı parametresi kendi yerel biçiminde belirtilir. Unicode'a atama gerekli değildir.
OPTIMIZED_SP_EXECUTESQL
Şunlar için geçerlidir: Microsoft Fabric'te SQL Server 2025 (17.x) Önizleme, Azure SQL Veritabanı ve SQL veritabanı
veritabanı kapsamlı yapılandırma OPTIMIZED_SP_EXECUTESQL etkinleştirildiğinde, sp_executesql
kullanılarak gönderilen toplu işlemlerin derleme davranışı, saklı yordamlar ve tetikleyiciler gibi nesnelerin şu anda kullandığı serileştirilmiş derleme davranışıyla aynı olur.
Toplu işler özdeş olduğunda (parametre farklılıkları hariç), OPTIMIZED_SP_EXECUTESQL
seçeneği derleme işleminin seri hale getirildiğini garanti etmek için zorlama mekanizması olarak bir derleme kilidi elde etmeye çalışır. Bu kilit, birden çok oturum aynı anda sp_executesql
çağırırsa, ilk oturum derleme işlemini başlatıldıktan sonra özel derleme kilidi elde etmeye çalışırken bu oturumların beklemesini sağlar.
sp_executesql
ilk yürütmesi derlenmiş planını derler ve plan önbelleğine ekler. Diğer oturumlar derleme kilidinde beklemeyi durdurur ve kullanılabilir duruma geldikten sonra planı yeniden kullanabilir.
OPTIMIZED_SP_EXECUTESQL
seçeneği olmadan, sp_executesql
aracılığıyla yürütülen aynı toplu işlemlerin birden çok çağrısı paralel olarak derlenir ve bazı durumlarda plan önbelleği girdilerinin yerini alan veya yinelenen plan önbelleğine kendi derlenmiş planının kopyalarını yerleştirir.
Not
OPTIMIZED_SP_EXECUTESQL
veritabanı kapsamlı yapılandırmasını etkinleştirmeden önce, otomatik güncelleştirme istatistikleri etkinleştirildiyse, ASYNC_STATS_UPDATE_WAIT_AT_LOW_PRIORITY veritabanı kapsamlı yapılandırma seçeneğiyle otomatik güncelleştirme istatistikleri zaman uyumsuz seçeneğini de etkinleştirmeniz gerekir. Bu iki seçeneğin etkinleştirilmesi, uzun derleme süreleriyle ilgili performans sorunlarının aşırı, kilit yöneticisi özel kilitleri (LCK_M_X) ve WAIT_ON_SYNC_STATISTICS_REFRESH
beklemeleri olasılığını önemli ölçüde azaltabilir.
OPTIMIZED_SP_EXECUTESQL
varsayılan olarak kapalıdır. veritabanı düzeyinde OPTIMIZED_SP_EXECUTESQL
etkinleştirmek için aşağıdaki Transact-SQL deyimini kullanın:
ALTER DATABASE SCOPED CONFIGURATION SET OPTIMIZED_SP_EXECUTESQL = ON;
İzinler
genel rolüne üyelik gerektirir.
Örnekler
A. SELECT deyimi yürütme
Aşağıdaki örnek, SELECT
adlı katıştırılmış parametreyi içeren bir @level
deyimi oluşturur ve yürütür.
EXECUTE sp_executesql N'SELECT * FROM AdventureWorks2022.HumanResources.Employee
WHERE BusinessEntityID = @level', N'@level TINYINT', @level = 109;
B. Dinamik olarak oluşturulmuş bir dize yürütme
Aşağıdaki örnekte, dinamik olarak oluşturulmuş bir dize yürütmek için sp_executesql
kullanımı gösterilmektedir. Örnek saklı yordam, bir yıl boyunca satış verilerini bölümlendirmek için kullanılan bir tablo kümesine veri eklemek için kullanılır. Yılın her ayı için aşağıdaki biçime sahip bir tablo vardır:
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)
);
Bu örnek saklı yordam, doğru tabloya yeni siparişler eklemek için dinamik olarak bir INSERT
deyimi oluşturur ve yürütür. Örnek, verileri içermesi gereken tablonun adını oluşturmak için sipariş tarihini kullanır ve ardından bu adı bir INSERT
deyimine ekler.
Not
Bu, sp_executesql
için temel bir örnektir. Örnekte hata denetimi yoktur ve sipariş numaralarının tablolar arasında yinelenmeyeceklerini garanti etme gibi iş kuralları denetimleri yoktur.
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
Bu yordamda sp_executesql
kullanmak, parametre işaretçilerinin kullanılmasına izin verdiğinden dinamik olarak oluşturulan dizeyi yürütmek için EXECUTE
kullanmaktan daha verimlidir. Parametre işaretçileri, Veritabanı Altyapısı'nın oluşturulan sorgu planını yeniden kullanma olasılığını daha yüksektir ve bu da ek sorgu derlemelerini önlemeye yardımcı olur.
EXECUTE
ile, parametre değerleri farklı olduğundan ve dinamik olarak oluşturulan dizenin sonuna eklendiğinden her INSERT
dizesi benzersizdir. Yürütülürken sorgu, planın yeniden kullanılmasını teşvik edecek şekilde parametrelendirilmeyecek ve her INSERT
deyimi yürütülmeden önce derlenmelidir ve bu da sorgunun plan önbelleğine ayrı bir önbelleğe alınmış girdisini ekler.
C. OUTPUT parametresini kullanma
Aşağıdaki örnek, OUTPUT
deyimi tarafından oluşturulan sonuç kümesini SELECT
parametresinde depolamak için bir @SQLString
parametresi kullanır. Ardından SELECT
parametresinin değerini kullanan iki OUTPUT
deyimi yürütülür.
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;
Örnekler: Azure Synapse Analytics ve Analytics Platform Sistemi (PDW)
D. SELECT deyimi yürütme
Aşağıdaki örnek, SELECT
adlı katıştırılmış parametreyi içeren bir @level
deyimi oluşturur ve yürütür.
EXECUTE sp_executesql
N'SELECT * FROM AdventureWorksPDW2012.dbo.DimEmployee WHERE EmployeeKey = @level',
N'@level TINYINT;',
@level = 109;