Makale Özeti

SQL Server 2005 ile birlikte duyurulan CLR Desteğini nasıl kullanacağına dağir, Stored Procedure örnekleri olan bir makale

Makale

CLR Destekli Stored Procedure Yazmak - I

Biliyorsunuzki SQL Server 2005 ve Visual Studio 2005 geliyor, Microsoft 6 Kasımda bu iki ürünüde piyasaya çıkartacak ve yepyeni özellikler, hayatımızı kolaylaştıracak çok fazla işlevsel özellikleri bulacağız, bu yeniliklerin en önemlilerinden bir taneside SQL Server da olacak, SQL Server artık CLR destekli (yani Vb.Net yada C# kodlarını) çalıştırabiliyor olacak. Bu makalenin amacı ise bu işin beta larda nasıl yapılacağını anlamak. Benim kullandığım platform, SQL Server 2005 CTP (SQL Server 9.0.1116) ve Visual Studio 2005 Beta 2. önceki sürümlere göre bazı değişiklikleri var özellikle yeni eklenmiş olan Context Connection=true deyimi mevcut. Bu deyim vasıtası ile yazdığımız Stored Procedure ler biraz daha Ado.Net yapısına benzetilmiş durumda, önceden Stored Procedure yi yazmak için sürekli SqlContext nesnesini kullanmak zorunda kalıyorduk (örneğin Dim conn as SqlConnection = SqlContext.GetConnection() gibi) daha farklıydı, ancak artık dahada kolaylaştırılmış durumda.

Hemen örneğimize geçelim, örneğimizde Vb.Net ile Stored Procedure ler yazacağız, ancak nasıl ? biliyorsunuzki, örneğin bir Windows uygulaması yaratmak istiyorsanız, Windows Application Template ini kullanıyoruz, yada Asp.Net uygulaması kullanacaksak, Asp.Net Web Site Template ini kullanıyoruz, Visual Studio 2005 ilede yeni bir Template geliyor, SQL Server Project, bu Template bize gerekli NameSpaceleri getiriyor, ve Stored Procedure ü daha rahat yazmamız sağlıyor.

Visual Studio 2005 imizi açıp, Create Project diyoruz daha sonra Visual Basic altından Database i oradanda uygulama tipi olarak SQL Server Project i seçiyoruz ve isim olarakta YazGelistirOrnek giriyoruz, Tamam a bastığımızda karşımıza Add Database Reference ekranı geliyor, bu ekranda hangi veri kaynağına bağlanmak istediğimiz soruluyor, seçebiliriz yada seçmeyebiliriz çok önemli değil (nedenini bu makalenin ikinci bölümünde bulabilirsiniz.) şimdilik bir tane seçelim, AdventureWorks veri tabanına bağlanabilirsiniz. Bir Veritabanını seçtikten sonra karşınıza bir soru geliyor, bu soru sizin CLR destekli yazdığınız Stored Procedure nin Debug yeteneğinin olması için bunu aktifleştirmeniz gerektiğini söylüyor, eğer aktifleştirmezseniz Makalenin ikinci bölümünde bir script bloğunu kullanmanız gerekiyor. Biz şimdilik aktifleştirmesini isteyelim ve Yes e basalım.

Bize bir Test.sql ve AssemblyInfo.vb dosyalarımızı ekledi. Ancak gördüğünüz gibi Stored Procedure yi yazacağım bir dosya yok, bunun için bir Stored Procedure eklemeliyim, Projeye sağ tuş, Add ve Stored Procedure yi seçin. İsmine GetPersonAddressType yazın ve Add e tıklayın.

Karşınıza şöyle bir şablon çıkacak

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 kullandığımız NameSpacelere bakalım, System ve System.Data bildiğiniz gibi standart, System.Data.Sql çok önemli değil, System.Data.SqlTypes bizim Sql Server da kullanacağımız veri türlerini örneğin, SqlString (nvarchar ımızın yerini tutuyor), SqlInt32 gibi, Microsoft.SqlServer.Server da ise Sql Server a özel class lar mevcut, örneğin metodudun Attribute ına bakarsanız o namespace den gelme. Şimdi metodumuzu inceleyelim, metodumuz shared tanımlı, eğer Stored Procedure yazmak istiyorsanız Shared olması gerekiyor. Bunun dışında SqlProcdure olarak metodun imzalanmasından başka bir ekstralık yok.

Şimdi amacımız AdventureWorks veritabanındaki, Person shemasındaki AddressType tablosunun tümünü alabilmek, bunun için aşağıdaki kodu yazın. 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

Yukarıdaki kodu hızlıca inceleyelim, ilk olarak System.Data.SqlClient Namespace ini ekledim, ki böylece SqlConnection, SqlCommand tazrındaki yapıları kullanabileyim.

Daha sonra bir SqlConnection tanımladım, ancak ConnectionString ine sadece “Context Connection=true” yu ekledim, böylece SQL server kendi içindeki Connectionlardan kullanması gerektiğini anlayacak, daha sonra bir SqlCommand ekledim, bildiğiniz gibi CommandText ini verdim, ve az önce yarattığım Connection ı ona atadım. Bir SqlPipe tanımladım, SqlPipe bizim verilerimizi döndüren class, anca dikkat edin instancesini SqlContext.Pipe ile oluşturdum. Böylece bu Context de çalıştığını anlattım. Connection ı açtım ve SqlPipe ımın Send metodu ile oluşan (comm.ExecuteReader SqlDataReader döndürür.) SqlDataReader ımı yolladım. Son iş ise açmış olduğum Connection ı kapattım. Makaleninde başında belirttiğim gibi biraz daha Ado.Net kullanımına yaklaştırılmış durumda. Peki şimdi örneğimizin nasıl çalıştığını inceleyelim, Visual Studio 2005 ile Sql Server 2005 CTP sürümü birbiri ile tam entegre çalışabiliyorlar, biraz ileride ben komutlarını yazacağım ama ilk örneğimizi çabuk uygulamak için projemize sağ tuş Build diyelim, eğer bir problem yoksa yine Projemize sağ tuş bu sefer Deploy diyelim. Deploy dediğimizde, Visual Studio 2005 yazdığımız bu dll i Sql Server 2005 ekleyecek ve benim için otomatik olarak Stored Proceduremi verdiğim isimde oluşturacak. Bunun için hemen SQL Server Management Studio yu açın ve AdventureWorks veritabanını inceleyin. Aşağıdaki şekle bakabilirsiniz.

 

Gördüğü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 yazdığım Stored Procedure yi ekledi. İsminide benim metoda verdiğim isim olarak (yani dbo.GetPersonAddressType olarak, başındaki dbo şemasını anlatıyor) bize sadece çalıştırmak kaldı. SQL Server Management Studio nun toolbarlarındaki sol üstten New Query Buttonuna basın, buradanda Database Engine Query i çalıştırın (standart olarak Master gelebilir, hemen altındaki ComboBox dan AdventureWorks ü seçin) buraya

exec dbo.GetPersonAddressType

yazın ve sonucu kendi gözleriniz ile görün :)

peki biz niye .Net ile Stored Procedure yazalım ? aslında cevabı çok basit, .Net bir platform ve çok fazla artısı var, yazılmış hazır class lar hazır metotlar var. Bir program yazarken zaten .Net kullanıyoruz, ancak SQL Server a yada başka bir Veritabanı sistemine geldiğimizde, başka bir platform ile uğraşıyoruz, onu öğrenmek zorunda kalıyoruz ve genelde ANSII SQL standartlarını desteklemek zorunda olduğu için dilin bazı sınırları oluyor. Bu yüzden SQL i de geliştirip başka bir dil oluşturmak zorunda kalıyorlar örneğin T-SQL (yada PL/SQL) gibi bu sefer bambaşka bir platformda başka bir dil ile kodlama yapmanız gerekiyor. Yani bir yerde .Net dili yazıyorsunuz bir yerde T-SQL. Ve maalesef T-SQL in çok fazla sınırı var. İşte CLR entegrasyonun en önemli noktası bu, programcılar tek bir dil bilip bu dil ile uğraşabiliyorlar (tabiiki yine SQL yazıyorsunuz, ancak T-SQL yada PL/SQL gibi farklı yapıları ile uğraşmıyorsunuz) ve bununla birlikte .Net gibi çok gelişmiş bir platformu kullanıyorsunuz.

 

Ancak nerede ve ne zaman .Net destekli Stored Procedure yi kullanacağımız da önemli.

Örneğin sadece veri çekecekseniz, T-SQL destekli Stored Procedure çok daha performanslı çalışacaktır, ancak daha kompleks işlemler yapıyorsanız, örneğin iki farklı tablodan verileri çekip, istediğiniz kriterlere uyuyormu diye bakıp, sonra bunların birleştirilmiş halini geriye döndürmek gibi bir işlemse, yada Stored Procedure içinde örneğin bir dosyaya erişmek gerekiyorsa bir XML okunup, ona göre başka bir iş yapmak gerekiyorsa .Net destekli Stored Procedure ler kullanmak çok daha mantıklı.

 

Bir sonraki makalede ise, parametre olarak bir değişken alıp o değişkene göre kayıt döndüren bir Stored Procedure, OUTPUT veri tipini ve Stored Procedure ün geriye değer döndürmesi işlemini yapacağız ve .Net ile yazdığımız bu Stored Procedure ü nasıl .Nette kullanacağımıza bakacağız.

İstek, Öneri ve eleştirileriniz için aşağıdaki mailimi kullanabilirsiniz.                

Levent Cenk ÇAĞLAR

cenk.caglar@yazgelistir.com