Mssql üzerinde procedure yazmak ve daha performanslı çalışmasını sağlamak

Codx

Katılımcı Üye
30 Tem 2017
309
1




Merhabalar, iyi forumlar herkese.

Başlıktan anlaşılacağı üzere T-SQL üzerinde bir Store Procedure nasıl yazılır. Bu Procedure nasıl parametre alır ve sektörde daha performanslı çalışması için hangi teknik kullanılır bunlardan bahsedeceğim. Konumuza geçelim.

SQL Server Management Studio ve Nortwind veri tabanı üzerinden anlatım sağlayacağım.

Nortwind veri tabanını seçip new query diyerek sorgumuzu yazmaya başlayalım.



Procedure oluşturmak için;

Kod:
CREATE PROC [procedure adi]

Şeklinde isim vermeliyiz.

Sonrasinda göndermek istediğimiz parametreyi tanımlamalıyız. Bu tanımlamayı yaparken;

Kod:
    [USER=530942]stm[/USER] VARCHAR(10)

gbi @ işareti ile başlayarak isimlendirmeli daha sonrasında ise tipini belirlemeliyiz.

Neden char değil varchar kullandığıma ise kısaca değinecek olursam, char(10) dediğim zaman 10 elemanlı bir char dizisi açmış olurum. Varchar(10) dediğimde yine 10 elemanlı bir char dizisi açmış olurum.

Farkı ise şudur;

Ben char(10) kullanırken eğer 3 karakterlik bir veri gönderirsem geri kalan 7 karakteri boş bir şekilde yer işgal eder. Varchar(10) dedikten sonra ise 3 karakterli bir veri gönderirsem sadece 3 elemanlık bir dizi oluşturur 7 adat boş veri alanı oluşturmaz.

Ben sadece mantığını anlatmak için kısa bir sorgu yazacağım ve 2 adet parametresi olacak.



Kodları açıklayalım;

Kod:
CREATE PROC getCustomersWhereCountry 
--getCustomersWhereCountry  adında bir proc create etmek istediğimi belirttim
    [USER=807188]CounTRy[/USER] VARCHAR(10), 
--ilk parametremi adlandırdım ve tipini belirttim
    [USER=23497]City[/USER] VARCHAR(10) 
--aynı şeyi ikinci parametrem için de yaptım

Parametrelerimi tanımladıktan sonra AS diyerek Procedure'umu yazmaya başlıyorum.
Kod:
CREATE PROC getCustomersWhereCountry 
    [USER=807188]CounTRy[/USER] VARCHAR(10),
    [USER=23497]City[/USER] VARCHAR(10)
AS
	SELECT * 
        --* ile bütün kolonları listeleyeceğimi belirtiyorum bunun yerine sadece görmek istediğim kolonların isimlerini de yazabilirm
	FROM Customers
        --Customers tablosundan veri çekeceğimi belirtiyorum
	WHERE Country =    [USER=807188]CounTRy[/USER] AND City =    [USER=23497]City[/USER]
--burada yukarıda parametre olarak gönderdığım değerleri Where colon_adı = aranan_deger şeklinde gönderiyorum birden fazla olduğu için and 
--diyerek sınırsız sayıda kriter ekleyebilirim

Procedur'un son hali;



Çalıştırmak istediğimiz kod bloğunu seçip F5'e basark kodumuzu çalıştırıyoruz ve hatasız çalıştığından emin oluyoruz.



Procedurumuzu temel yazım mantığını öğrendik. Şimdi nasıl çalıştıracağımızı öğrenelim.

Procedure'leri çalıştırmak için;

Kod:
EXEC proc_adi parametre

Şeklinde çalıştırılabilir. Biz iki parametre gönderecektik, ilki ülke ikincisi şehirdi.



Bakın zaten çıkan uyarıda kaç parametre aldığı hakkında bana bilgi veriyor. Ben UK'da London şehrinde kayıtlı olanları listelemek istiyorum. Bu sebeple parametrelerimi bu şekilde gönderiyorum.

Çalıştıralım ve dönen sonuçlara bakalım;



Bakın görmek istediğim sonuçları bana aynen listeledi.

Temel çalışma mantığını gördükten, sonra sözünü verdiğim sektörde sorgularımızın daha performanslı çalışması için kullanılan o tekniğin ne olduğundan bahsedelim.

Bu tekniğin kullanım sebebi şudur;

MSSQL bizim istediğimiz sonuçları veri tablolarından seçer ve indexleyerek bize sunar. Bunun ile birlikte her sorgu çalışırken syntax hatası var mı? İstenen kolonlar tablolarda mevcut mu? Bu kontrollerden de geçer. Bu 100 satırlık bir sonuç döndürdüğü sürece bir sorun oluşturmaz. Lakin veriler birkaç yüz binleri bulmaya başladığı zaman yavaşlık söz konusu olacaktır, ve müşteri beklemeyi hiç sevmez. Bu olay bu şekilde gerçekleşmese de bize yine aynı sonuçları döndürecekir. Bunu atlatmak için sorgu bir değişkenin içerisine atılır. Procedure sonunda bu değişkenin adı yazılarak çalıştırılır. Biz yine dışarıdan istediğimiz her yerden yukarıdaki şekilde EXEC proc_adı parametre şeklinde kullanmaya devam edebiliriz.

Önce gösteriyim sonrasında da açıklayacağım.



Öncelikle bu isimde bir procedure bulunduğu için var olanı yeniden create edemem o yüzden create yerine ALTER yazarak bunu güncelleyeceğimi belirtmem gerekiyor. BEGIN - END aralığında ise procedurumun nerede başlayıp nerede bittiğini belitmelitim. AS komutundan önce zaten iki parametre tanımlamıştım. Burada BEGIN - END komutlarının ihtiyacı proc içerisinde çalışacak dışarısı ile bir bağlantısı olmayacak değişken tanımı yaptığımdan dolayı doğuyor. Bu haliyle proc çalışmayacaktır. Bunu bir değişkenin içerisine koyduk evet ama bunu içeride EXEC etmedik. Değişkenin içerisine yazdığım metne dışarıdan parametre göndereceğimi bildirmek için ''' stm+''' şeklinde bir kullanım yapmalıyım. Bütün bunları dahil ettiğim zaman kodun son hali şöyle olacaktır;



Bu şekilde çalışacaktır.

Deneyelim sonrasında da analiz edelim.



Sorunsuz ve istediğimiz gibi çalıştığına göre kodlar üzerinden eklenen kısımları açıklayayım;
Kod:
ALTER PROC getCustomersWhereCountry 
    [USER=807188]CounTRy[/USER] VARCHAR(10),
    [USER=23497]City[/USER] VARCHAR(10)
AS
BEGIN
DECLARE    [USER=530942]stm[/USER] VARCHAR(100)
	
 	set    [USER=530942]stm[/USER] ='SELECT * FROM Customers WHERE Country = '''    [USER=807188]CounTRy[/USER]+''' AND City = '''     [USER=23497]City[/USER]+''''
			print     [USER=530942]stm[/USER])
			EXEC     [USER=530942]stm[/USER])
END

Kod:
set    [USER=530942]stm[/USER] ='SELECT * FROM Customers WHERE Country = '''    [USER=807188]CounTRy[/USER]+''' AND City = '''     [USER=23497]City[/USER]+''''

SET stm diyerek değişkenin içerisine metnimi tanımlıyorum. Dışarıdan parametre göndermek istemeseydim eğer sadece iki '' arasında yazacak ve kodumu çalıştıracaktım. Fakat ben dışarıdan parametre göndermek istiyorum. İki tırnak arasında CounTRy+ yazabilirdim. Procedure'u oluştururken bana hiç bir hatada vermezdi. Bakalım o zaman proc SQL'e nasıl bir sorgu gönderirdi. Print yazan satırın altında RETURN ifadesi ekliyorum. Bu sayede ekrana yazdırdıktan sonra çalıştırmaya çalışmayacak ve sadece stm içerisindeki metin nasıl bir sorgu olarak gidiyor bunu göreceğiz.



Proc'u alter ile güncelledim, ve dediğim ifadeyi ekleyerek EXEC'i çalıştırdım. Ekrana verdiği sorguyu çalıştırmak istediğim zaman bana hata verecektir.



Sorgu bu şekilde çalışmayacaktır. Invalid column name hatası verir, çünkü bunları veri olarak değil kolon adı olarak aratmaya çalışmaktadır. Bu sebeple bana bu hatayı döndürmektedir. Az önce parametrelerimin yanına üç adet tırnak koyma sebebim de buydu eğer öyle olsaydı nasıl olurdu? Sadece tırnakları düzelteceğim ve aynı EXEC'i çalıştıracağım.



Tırnakları düzelttikten sonra proc'un çalıştırmaya çalıştırdığı sorgu resimdeki gibidir. Bu şekilde yazdığım kodu analiz ederken doğru yazılmış mı? Diye test etmek için ben eklemiştim. Onun orada olması performansı etkileyen bir durum değildir.

Herkese iyi forumlar dilerim.

 
Son düzenleme:
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.