CLR Destekli Stored Procedure Yazmak
CLR Destekli Stored Procedure Yazmak - I
Biliyorsunuzki SQL Server 2005 ve Visual Studio 2005 geliyor, Microsoft 6 Kasimda bu iki ürünüde piyasaya çikartacak ve yepyeni özellikler, hayatimizi kolaylastiracak çok fazla islevsel özellikleri bulacagiz, bu yeniliklerin en önemlilerinden bir taneside SQL Server da olacak, SQL Server artik CLR destekli (yani Vb.Net yada C# kodlarini) çalistirabiliyor olacak. Bu makalenin amaci ise bu isin beta larda nasil yapilacagini anlamak. Benim kullandigim platform, SQL Server 2005 CTP (SQL Server 9.0.1116) ve Visual Studio 2005 Beta 2. önceki sürümlere göre bazi degisiklikleri var özellikle yeni eklenmis olan Context Connection=true deyimi mevcut. Bu deyim vasitasi ile yazdigimiz Stored Procedure ler biraz daha Ado.Net yapisina benzetilmis durumda, önceden Stored Procedure yi yazmak için sürekli SqlContext nesnesini kullanmak zorunda kaliyorduk (örnegin Dim conn as SqlConnection = SqlContext.GetConnection() gibi) daha farkliydi, ancak artik dahada kolaylastirilmis durumda.
Hemen örnegimize geçelim, örnegimizde Vb.Net ile Stored Procedure ler yazacagiz, ancak nasil ? biliyorsunuzki, örnegin bir Windows uygulamasi yaratmak istiyorsaniz, Windows Application Template ini kullaniyoruz, yada Asp.Net uygulamasi kullanacaksak, Asp.Net Web Site Template ini kullaniyoruz, Visual Studio 2005 ilede yeni bir Template geliyor, SQL Server Project, bu Template bize gerekli NameSpaceleri getiriyor, ve Stored Procedure ü daha rahat yazmamiz sagliyor.
Visual Studio 2005 imizi açip, Create Project diyoruz daha sonra Visual Basic altindan Database i oradanda uygulama tipi olarak SQL Server Project i seçiyoruz ve isim olarakta YazGelistirOrnek giriyoruz, Tamam a bastigimizda karsimiza Add Database Reference ekrani geliyor, bu ekranda hangi veri kaynagina baglanmak istedigimiz soruluyor, seçebiliriz yada seçmeyebiliriz çok önemli degil (nedenini bu makalenin ikinci bölümünde bulabilirsiniz.) simdilik bir tane seçelim, AdventureWorks veri tabanina baglanabilirsiniz. Bir Veritabanini seçtikten sonra karsiniza bir soru geliyor, bu soru sizin CLR destekli yazdiginiz Stored Procedure nin Debug yeteneginin olmasi için bunu aktiflestirmeniz gerektigini söylüyor, eger aktiflestirmezseniz Makalenin ikinci bölümünde bir script blogunu kullanmaniz gerekiyor. Biz simdilik aktiflestirmesini isteyelim ve Yes e basalim.

Bize bir Test.sql ve AssemblyInfo.vb dosyalarimizi ekledi. Ancak gördügünüz gibi Stored Procedure yi yazacagim bir dosya yok, bunun için bir Stored Procedure eklemeliyim, Projeye sag tus, Add ve Stored Procedure yi seçin. Ismine GetPersonAddressType yazin ve Add e tiklayin.
Karsiniza söyle bir sablon çikacak
Imports System
Imports System.Data
Imports System.Data.Sql
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Partial Public Class StoredProcedures
<Microsoft.SqlServer.Server.SqlProcedure()> _
Public Shared Sub GetPersonAddressType ()
’ Add your code here
End Sub
End Class
Buradaki kodu bir inceleyelim, öncelikle kullandigimiz NameSpacelere bakalim, System ve System.Data bildiginiz gibi standart, System.Data.Sql çok önemli degil, System.Data.SqlTypes bizim Sql Server da kullanacagimiz veri türlerini örnegin, SqlString (nvarchar imizin yerini tutuyor), SqlInt32 gibi, Microsoft.SqlServer.Server da ise Sql Server a özel class lar mevcut, örnegin metodudun Attribute ina bakarsaniz o namespace den gelme. Simdi metodumuzu inceleyelim, metodumuz shared tanimli, eger Stored Procedure yazmak istiyorsaniz Shared olmasi gerekiyor. Bunun disinda SqlProcdure olarak metodun imzalanmasindan baska bir ekstralik yok.
Simdi amacimiz AdventureWorks veritabanindaki, Person shemasindaki AddressType tablosunun tümünü alabilmek, bunun için asagidaki kodu yazin. Görüceksiniz ki çok kolay.
Imports System
Imports System.Data
Imports System.Data.Sql
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Imports System.Data.SqlClient
Partial Public Class StoredProcedures
<Microsoft.SqlServer.Server.SqlProcedure()> _
Public Shared Sub GetPersonAddressType()
Dim conn As SqlConnection = New SqlConnection
conn.ConnectionString = "Context Connection=true"
Dim comm As SqlCommand = New SqlCommand
comm.CommandText = "SELECT * FROM Person.AddressType"
comm.Connection = conn
Dim sp As SqlPipe = SqlContext.Pipe
conn.Open()
sp.Send(comm.ExecuteReader)
conn.Close()
End Sub
End Class
Yukaridaki kodu hizlica inceleyelim, ilk olarak System.Data.SqlClient Namespace ini ekledim, ki böylece SqlConnection, SqlCommand tazrindaki yapilari kullanabileyim.
Daha sonra bir SqlConnection tanimladim, ancak ConnectionString ine sadece “Context Connection=true” yu ekledim, böylece SQL server kendi içindeki Connectionlardan kullanmasi gerektigini anlayacak, daha sonra bir SqlCommand ekledim, bildiginiz gibi CommandText ini verdim, ve az önce yarattigim Connection i ona atadim. Bir SqlPipe tanimladim, SqlPipe bizim verilerimizi döndüren class, anca dikkat edin instancesini SqlContext.Pipe ile olusturdum. Böylece bu Context de çalistigini anlattim. Connection i açtim ve SqlPipe imin Send metodu ile olusan (comm.ExecuteReader SqlDataReader döndürür.) SqlDataReader imi yolladim. Son is ise açmis oldugum Connection i kapattim. Makaleninde basinda belirttigim gibi biraz daha Ado.Net kullanimina yaklastirilmis durumda. Peki simdi örnegimizin nasil çalistigini inceleyelim, Visual Studio 2005 ile Sql Server 2005 CTP sürümü birbiri ile tam entegre çalisabiliyorlar, biraz ileride ben komutlarini yazacagim ama ilk örnegimizi çabuk uygulamak için projemize sag tus Build diyelim, eger bir problem yoksa yine Projemize sag tus bu sefer Deploy diyelim. Deploy dedigimizde, Visual Studio 2005 yazdigimiz bu dll i Sql Server 2005 ekleyecek ve benim için otomatik olarak Stored Proceduremi verdigim isimde olusturacak. Bunun için hemen SQL Server Management Studio yu açin ve AdventureWorks veritabanini inceleyin. Asagidaki sekle bakabilirsiniz.

Gördügünüz gibi Assemblies bölümüne benim dll imi ekledi (ismi projenin ismi olarak) ve Stored Procedures bölümüne de benim yazdigim Stored Procedure yi ekledi. Isminide benim metoda verdigim isim olarak (yani dbo.GetPersonAddressType olarak, basindaki dbo semasini anlatiyor) bize sadece çalistirmak kaldi. SQL Server Management Studio nun toolbarlarindaki sol üstten New Query Buttonuna basin, buradanda Database Engine Query i çalistirin (standart olarak Master gelebilir, hemen altindaki ComboBox dan AdventureWorks ü seçin) buraya
exec dbo.GetPersonAddressType
yazin ve sonucu kendi gözleriniz ile görün :)

peki biz niye .Net ile Stored Procedure yazalim ? aslinda cevabi çok basit, .Net bir platform ve çok fazla artisi var, yazilmis hazir class lar hazir metotlar var. Bir program yazarken zaten .Net kullaniyoruz, ancak SQL Server a yada baska bir Veritabani sistemine geldigimizde, baska bir platform ile ugrasiyoruz, onu ögrenmek zorunda kaliyoruz ve genelde ANSII SQL standartlarini desteklemek zorunda oldugu için dilin bazi sinirlari oluyor. Bu yüzden SQL i de gelistirip baska bir dil olusturmak zorunda kaliyorlar örnegin T-SQL (yada PL/SQL) gibi bu sefer bambaska bir platformda baska bir dil ile kodlama yapmaniz gerekiyor. Yani bir yerde .Net dili yaziyorsunuz bir yerde T-SQL. Ve maalesef T-SQL in çok fazla siniri var. Iste CLR entegrasyonun en önemli noktasi bu, programcilar tek bir dil bilip bu dil ile ugrasabiliyorlar (tabiiki yine SQL yaziyorsunuz, ancak T-SQL yada PL/SQL gibi farkli yapilari ile ugrasmiyorsunuz) ve bununla birlikte .Net gibi çok gelismis bir platformu kullaniyorsunuz.
Ancak nerede ve ne zaman .Net destekli Stored Procedure yi kullanacagimiz da önemli.
Örnegin sadece veri çekecekseniz, T-SQL destekli Stored Procedure çok daha performansli çalisacaktir, ancak daha kompleks islemler yapiyorsaniz, örnegin iki farkli tablodan verileri çekip, istediginiz kriterlere uyuyormu diye bakip, sonra bunlarin birlestirilmis halini geriye döndürmek gibi bir islemse, yada Stored Procedure içinde örnegin bir dosyaya erismek gerekiyorsa bir XML okunup, ona göre baska bir is yapmak gerekiyorsa .Net destekli Stored Procedure ler kullanmak çok daha mantikli.
Bir sonraki makalede ise, parametre olarak bir degisken alip o degiskene göre kayit döndüren bir Stored Procedure, OUTPUT veri tipini ve Stored Procedure ün geriye deger döndürmesi islemini yapacagiz ve .Net ile yazdigimiz bu Stored Procedure ü nasil .Nette kullanacagimiza bakacagiz.
Makale Yazar : Levent Cenk ÇAGLAR
Düzenleme : SteaM