Dinamik SQL - EXEC (@SQL) ve EXEC SP_EXECUTESQL (@SQL)


96

Kullanarak SQL Server'da bir saklı yordamda dinamik bir SQL komutu çalıştırmanın gerçek dünyadaki artıları ve eksileri nelerdir?

EXEC (@SQL)

karşı

EXEC SP_EXECUTESQL @SQL

?

Yanıtlar:


96

sp_executesqlsorgu planının yeniden kullanımını teşvik etme olasılığı daha yüksektir. Kullanılırken sp_executesql, parametreler çağıran imzada açıkça tanımlanır. Bu mükemmel makale bu süreci anlatmaktadır .

Dinamik sql'nin birçok yönü için sık sık alıntı yapılan referans Erland Sommarskog'un okuması gereken: " Dinamik SQL'in Laneti ve Kutsaması ".


21

SP_EXECUTESQL ile ilgili en önemli şey, SQL enjeksiyonunu önemsiyorsanız çok iyi olan parametreli sorgular oluşturmanıza izin vermesidir.


1
Dinamik bir sql'yi onsuz parametreleyebileceğinizi sanmıyorum ??
DJ.

EXEC ('SELECT * FROM FOO WHERE ID =?', 123) parametre yer tutucusunun yerini alacak "?" 123 değeriyle ve ardından sorguyu yürütün ve SELECT * FROM FOO WHERE ID = 123 için bir sonuç döndürür
Peter Wone

1
Hata! Bu sözdizimi yalnızca bağlantılı sunucular için kullanılabilir.
Peter Wone

1
Sorguyu dinamik olarak oluşturup sql enjeksiyonunu önlemek için sp_executesql kullanmanın kesinlikle en büyük nedenlerinden biri.
Steven Rogers

5

Microsoft'un sp_executesql kullanma makalesi sp_executesql, executeifade yerine kullanılmasını önerir .

Bu saklı yordam parametre değiştirmeyi desteklediğinden , sp_executesql, EXECUTE'dan daha çok yönlüdür; ve sp_executesql, SQL Server tarafından yeniden kullanılma olasılığı daha yüksek olan yürütme planları ürettiğinden, sp_executesql, EXECUTE'dan daha etkilidir .

Yani, uzak take: kullanmayın Do executedeyimi . Kullanın sp_executesql.


7
Paket servisiniz her zaman geçerli değildir. Sp_executesql kullanarak verimlilik bonusu olmadığı durumlar vardır, ancak kodunuzu sql injection saldırısından koruyabilirsiniz. Bazen sp_executesql'i exec'yi kullanabileceğiniz şekilde kullanamazsınız, bu yüzden ... birisi dedi - sihirli bir değnek yoktur. Katılıyorum.
OzrenTkalcecKrznaric

Evet, Microsoft bunu " verimli olma olasılığı daha yüksek " olarak belirlemeliydi. Ve birkaç yıldır sektörün içinde olduğum için sp_executesql, yerine kullanılamayacak durumlar gördüm execute. Belki de vurgulamaya çalıştığım noktayı şu şekilde ifade etmeliyim: Mümkün olduğuncasp_executesql yerine kullanın . execute
Gan

2

Bu günlerde her zaman sp_executesql kullanırdım, gerçekten de parametreleri ve değişkenleri işleyen EXEC için bir sarmalayıcıdır.

Ancak, özellikle birden fazla veri tabanına yayılmış verilere sahip olduğunuz ve indeks taramalarını sınırlamak için bir KISITLAMA kullandığınız çok büyük veri tabanlarında sorguları ayarlarken OPTION RECOMPILE'ı unutmayın.

OPTION RECOMPILE kullanmadığınız sürece, SQL sunucusu sorgunuz için "herkese uyan tek boyut" yürütme planı oluşturmaya çalışır ve her çalıştırıldığında tam bir dizin taraması çalıştırır.

Bu, bir aramadan çok daha az etkilidir ve potansiyel olarak, sizin sorgulamadığınız aralıklarla sınırlandırılmış tüm dizinleri taradığı anlamına gelir: @


-2
  1. Değişkeni bildirin
  2. Komutunuzla ayarlayın ve sp'nin parametre değerlerini kullanma gibi dinamik parçalar ekleyin (burada @IsMonday ve @IsTuesday sp parametreleridir)
  3. komutu çalıştır

    declare  @sql varchar (100)
    set @sql ='select * from #td1'
    
    if (@IsMonday+@IsTuesday !='')
    begin
    set @sql= @sql+' where PickupDay in ('''+@IsMonday+''','''+@IsTuesday+''' )'
    end
    exec( @sql)
    

15
Bu, örneğin "a '; DROP DATABASE DATABASE_NAME; GO;';" koyarsanız SQL enjeksiyonuna açıktır. @IsMonday değişkeninde
Erik A. Brandstadmoen

@IsMonday int ise sql cezasına yatkın mı?
Vikas Rana

@VikasRana @IsMonday intdinamik SQL'de olamaz . @Sql'nin varcharveya olarak ilan edildiğine dikkat edinnvarchar
Weihui Guo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.