Parametreli stored procedure’lerin kullanılmadığı kuruluşlarda, çalışma sırasında oluşturulan T-SQL kodunun çalıştırılması gerekebilir. Dinamik SQL mekanizması sayesinde oluşturulan string değeri SQL Server tarafından komut olarak algılanır ve derlenip yürütülür.

Bu bölümde, sp_executesql sp’sini kullanarak dinamik SQL sorgusu kullanmayı göstereceğiz.

Dinamik SQL Oluşturma

Dinamik SQL’i neden kullanırız? Bir sorguyu çalıştırana kadar sorgunun çalışabilmesi için gerekli olan tüm parametreleri bilemeyebiliriz. Örneğin sorgu sonucunu başka bir nesneye (örneğin pivot sorgusuna) input olarak verilmesi sırasında veya runtime’da değişkenleri input olarak kullanan yönetimsel bakım rutini sırasında bu durum karşımıza çıkabilir.

T-SQL ile dinamik SQL ifadeleri iki yöntemle oluşturulabilir. İlk yöntem exec komutunun string değeriyle birlikte kullanılması, ikincisi ise sp_executesql sp’sinin kullanılmasıdır.

1. EXEC komutuyla bir string değeri aşağıda gösterildiği gibi input olarak kullanılabilir. Fakat bu durumda string değeriyle bilikte herhangi bir parametre kullanılamaz. EXEC komutunda sadece string değeri kullanılabilir. Bu örnekte string değerleri birleştirilerek sorgu oluşturulduğunu görüyoruz:

DECLARE @sqlstring AS VARCHAR(1000);
SET @sqlstring='SELECT empid,' + ' lastname '+' FROM HR.employees;'
EXEC(@sqlstring);
GO 

2. sp_executesql sp’sinde nput olarak string değerinin yanında ekstra parametreler de kabul edilmektedir. Aşağıdaki örnekte, sp_executesql procedure’üne verilen bir sorgu string’i gösterilmektedir:

DECLARE @sqlcode AS NVARCHAR(256) = N'SELECT GETDATE() AS dt';
EXEC sys.sp_executesql @statement = @sqlcode;
GO 

EXEC komutu parametre kabul etmediğinden dolayı query plan’ın yeniden kullanımını da desteklemez. Bu nedenle, dinamik SQL’den faydalanırken sp_executesql kullanmanız önerilir.

Dinamik SQL ile Sorgu Yazma

Dinamik SQL ile çalışmanın iki yöntemini öğrendik. Bu konuda sp_executesql kullanılan yönteme odaklanacağım.

EXEC runtime’da parametre alamadığından, sp_executesql daha çok tercih edilir. Dahası diğer yönteme göre sp_executesql ile oluşturulan execution plan daha çok yeniden kullanılabilir. Bu yöntemin en büyük avantajı da parametre veri türlerinin tanımlanmasıyla SQL injection saldırılarına karşı ekstra güvenlik sağlanmasıdır diyebiliriz.

sp_executesql kullanırken sorgu olduğu gibi string değeri şeklinde verilir:

DECLARE @sqlcode AS NVARCHAR(256) = N'<code_to_run>';
EXEC sys.sp_executesql @statement = @sqlcode;
GO 

Aşağıdaki örnekte, sp_executesql ile bir SELECT sorgusu çalıştırılmıştır:

DECLARE @sqlcode AS NVARCHAR(256) =  N'SELECT GETDATE() AS dt';
EXEC sys.sp_executesql @statement = @sqlcode;
GO 

sp_executesql’de şu iki parametreyi illaki tanımlamak gerekir:

  • @stmt: Sorgu tanımını tutan Unicode string değişkeni.
  • @params: Değişken ismi ve veri türü formunda virgülle ayrılmış parametre listesini tutan Unicode string değişkeni.

Bu ikisinden başka kendiniz parametre ilave etmek isterseniz, değişkenleri yazıp değer atamasını yaparak sp_executesql’de input olarak yazabilirsiniz.

Aşağıda çalışanların verisini çekmek için dinamik olarak oluşturulan sorgu sp_executesql ile SQL Server’a geçirilmiştir:

DECLARE @sqlstring AS NVARCHAR(1000);
DECLARE @empid AS INT;
SET @sqlstring = N'SELECT empid, lastname FROM HR.employees 
WHERE empid = @empid;'
EXEC sys.sp_executesql @statement = @sqlstring, @params=N'@empid AS INT', @empid = 5; 

Sonuç:

empid lastname
----- --------
5 Buck 

Not: sp_executesql ile önceki bölümde anlattığım OUTPUT parametrelerini de kullanabilirsiniz.

Kaynak:
Using sp_executesql
EXECUTE (Transact-SQL)