.NET İle SQL Server CLR Assemblies
0

SQL Server üzerinde geliştirme yaparken bilindiği gibi T-SQL ( Transact – SQL ) komutları kullanılır. T-SQL, hemen hemen tüm geliştirme ihtiyaçlarımızı karşılıyor olmasına rağmen bazı durumlarda ihtiyacımıza yetersiz kalabilmektedir. T-SQL dilinin yetersiz kaldığı durumlarda, Microsoft, .NET kütüphanelerini kullanmamıza imkân sağlayarak SQL Server ‘da ihtiyacımıza özel geliştirme yapmamıza altyapı oluşturmuştur. .NET ile SQL Server CLR konusuna geçmeden önce bazı temel bilgilerin ne olduğuna sırayla bakalım.

Not: Makale üzerinde C#.Net yazılım geliştirme dili kullanılacak olup, temel programlama bilginizin olması makaleyi daha iyi anlayabilmenizde yarar sağlayacaktır.

.NET Framework Nedir?

.Net Framework, .Net platformunun geliştirme, çalıştırma ve yayınlama işlemlerinin gerçekleştirildiği bir altyapıdır. .Net Framework Microsoft‘un kendi ürettiği yazılım geliştirme teknolojilerini tek çatı altına almak ve belirli standartlar çerçevesinde toplamak amacıyla oluşturulmuş olduğu bir teknolojidir.

.Net Framework’un esas amacı her yazılım geliştiricilerin her platform için (Mobil,Web,Masaüstü vb.) farklı programlama dillerini öğrenmesini ortadan kaldırmak olup bu sayede hem dilin popülaritesini arttırmak hem de yazılımcılara geliştirme kolaylığı sağlamaktır.

CLR (Common Language Runtime – Ortak Dil Çalışma Platformu)

CLR .Net platformunda yazılan kodların (C#,VB vb.) işletim sisteminin anlayacağı dile çeviren ara birimdir. Bu işlem sırasında uygulama kodu öncelikle MSIL (Microsoft Intermediate Language) çevrilir. MSIL‘e çevrilmesindeki esas amaç, işletim sisteminin anlayacağı dile çevrilmeden önce programlama dillerinden gelen kodları ortak bir noktada buluşturmaktır.

MSIL (Microsoft Intermadiate Language – Ara Dil)

Bir yazılımın işletim sistemi üzerinde çalışması için, Assembly adı verilen ve işletim sisteminin anlayacağı dil olan makine diline dönüştürülmesi gerekir.

.Net platformunda geliştirilen yazılım, Assembly ‘e dönüştürülmeden önce MSIL isimli ara dile dönüştürülür. Bu dönüşümün sebebi farklı dillerde yazılan kodların farklı şekilde Assembly’e dönüştürülmesidir. Bu farklılığı ortadan kaldırmak için geliştirilen kodlar makine diline dönüştürülmeden önce MSIL’e dönüştürülüp tüm programlama dilleri için ortak bir noktada buluşma sağlanmış oldu.

Daha sonra MSIL kodu işletim sisteminin anlayacağı dile dönüştürülecek ve çalıştırılacaktır.

JIT (Just In Time – Çalışma Anında Derleme)

MSIL‘e dönüştürülen kodlar, JIT(Just in time) derleyicileri yardımı ile Assembly‘e dönüştürülüp işletim sistemi üzerinde çalıştırmaya imkan sağlamaktadır.

JIT (Just In Time ) bellek (RAM) üzerinde çalıştığı için bazı durumlarda uygulamaların performansını arttırmak için hafıza üzerinde uygulamanın belli kısımlarını hafızaya alabilmektedir. Bu durum bellek durumu yeterli olmadığı zamanlarda olmaktadır. Bellek boşluk oranında göre farklı şekilde JIT yapısı çalışmaktadır. Bunlar;

ECONOJIT

Boş Bellek oranı yeterli olmadığı durumda kullanılır. Bellek üzerinde uygulamanın hiçbir bölümü tutulmaz. Bu yöntem uygulamanın çalışma süresini uzatır.

JIT

Normal JIT’te derleme işlemini varsayılan ayarlara göre yapar. MSIL kodu önbelleğe alınır. Uygulama yeniden çalıştırıldığında kod önbellekten çalıştırılacağı için performans artışı sağlar.

PREJIT

Bu derleme yönteminde tüm bilgiler bellekte tutulur. Bu sebeple fazla miktarda bellek ihtiyacı gerektirir. Tüm bilgiler bellekte tutulduğu için uygulama performansını arttırmaktadır.

.NET İle SQL SERVER CLR

CLR, Microsoft SQL Server tarafından SQL Server 2005 ve sonraki versiyonlarda desteklenmiştir. SQL CLR sayesinde Stored Procedure, Trigger, UDT (User-Defined type), UDF (User-Defined Function) ve UDA (User-Defined Aggregate) Managed Code olarak yazılabilir. Özellikle T-SQL’de olmayan ya da yazılması daha karmaşık olan işlemlerde, .Net Assembly kullanmak avantaj sağlamaktadır.

SQL Server Üzerinde CLR Integration Aktifleştirilmesi

.NET kodlaması ile geliştireceğimiz bir nesnenin (Stored Procedure,Function vb) SQL Server tarafından kullanılabilmesi için, SQL Server CLR Integration özelliği aktif hale getirilmelidir. Bunun için aşağıdaki kodu çalıştırmamız gerekmektedir.


Resim-1

SQL Server Instance‘nda CLR seçeneğinin durumunu aşağıdaki T-SQL cümlesi ile sorgulayabilirsiniz.


Resim-2

CLR Tür Yapısı:

Veritabanı Nesnesi.Net Framework Assembly TipiAçıklama
Scalar-valued functionPublic statik methodTek bir değer döndüren UDF
Table-valued functionPublic statik methodTablo döndüren UDF
Stored ProcedurePublic static methodDDL,DML sorularını çalıştırır, çıkış parametresi döndürür.
User-defined aggregate functionClass or structureÖzet değer döndüren UDA
User-defined typeClass or structureSQL Server içerisinde mevcut olmayan kullanıcı tarafından oluşturulan veri türü
Triggers (DML ve DDL)Public static methodDDL veya DML olayı meydana geldiğinde otomatik olarak tetiklenecek saklı yordam türü.

Ado.Net ile CLR Programlama

Ado.Net ile CRL geliştirilirken .Net Framework tarafında kullanılan dört ana sınıf vardır. Bunlar;

SqlContext

SqlPipe

SqlTriggerContext

SqlDataRecord

CLR İLE Stored Procedure

Stored Procedure dilimize saklı yordam olarak geçmiştir Kısaca Stored Procedure, SQL Server veri tabanı içerisinde tutulan ve ilk derlemeden sonra tekrar derleme ihtiyacı olmayan T-SQL ifadeleridir. Saklı yordamlar performaslı bir yapıya sahip olduğu gibi, network trafiği içinde tasarruf yapılmasına da imkan sağlar.

.NET CLR ile AdventureWorks örnek veritabanımızda bulunan ürünlerin listesini alabileceğimiz bir örnek proje geliştirelim.

Örneğimiz Visual Studio 2017
ve SQL Server 2017 ile yapılacaktır.

Visual Studio 2017′ yi çalıştırdıktan sonra File => New=> Project menüsünden, proje Template’ lerinin (Şablon) listelendiği ekranı açıyoruz.

Resim-3

Karşımıza gelen ekranda Other Languages dizini altında bulunan SQL Server seçiyor ve ortadaki bölümden “SQL Server Database Project” Template’ ni seçtikten sonra proje adı olarak “CLRFirstStoredProcedure” belirleyip OK düğmesine tıklayıp projemizi oluşturuyoruz.

Projemiz oluşturulduktan sonra Solution Explorer pencesinde bulunan CLRFirstStoredProcedure sağ tıklayıp New Item seçeneğini seçiyor ve aşağdaki ekrandan SQL CLR C# sekmesi içinde olan SQL CLR C# Stored Procedure seçip ismini “Usp_GetProductList” olara değiştirip Add komutunu veriyoruz.

Resim-4

Oluşturmuş olduğumuz Usp_GetProductList.cs kod sayfamız içerisine veritabanında bulunan ürünleri sorgulayacağımız kodlarımızı aşağıdaki gibi yazıyoruz.

using (SqlConnection con = new
SqlConnection(“context connection=true”))

{


if (con.State != ConnectionState.Open)

{

con.Open();

}


using (SqlCommand cmd = new
SqlCommand(“SELECT * FROM Production.Product”, con))

{


SqlContext.Pipe.ExecuteAndSend(cmd);

}

}

Select işlemi için alternatif olarak aşağıdaki komutu da tercih edebilirsiniz;

SqlContext.Pipe.Send(cmd.ExecuteReader());

Resim-5

Kodlarımızı yazdıktan sonra oluşturmuş olduğumuz saklı yordamı veritabanımıza aktarmak için sırası ile aşağıdaki işlemleri uyguluyoruz.

Solution Explorer pencesinde bulunan projemize sağ tıklayıp Publish (Yayınla) komutunu seçiyoruz.

Resim-6

Karşımıza Publish Database ekranı gelecektir. Bu ekranda Target Database Connection ‘ı seçmek için Edit düğmesine tıklıyoruz.

Resim-7

Edit düğmesine tıkladıktan sonra karşımıza gelen Connection Properties penceresinde veritabanı bağlantı bilgilerimizi giriyor ve saklı yordamı oluşturacağımız veritabanını seçiyoruz.

Resim-8

OK düğmesine tıkladıktan sonra tekrar Publish Database ekranına geliyoruz ve bu ekrandan Publish düğmesine tıklayıp oluşan Assembly‘ i seçmiş olduğumuz veri tabanına aktarıyoruz ediyoruz.

Resim-9

Publish düğmesine tıkladıktan sonra Publish durumunu otomatik açılan Data Tools Operations penceresinden izliyoruz.

Resim-10

Publish işlemi başarıyla tamamlandıktan sonra SQL SERVER Management Studio ile AdventureWorks => Programmability=> Assemblies altında CLRFirstStoredProcedure oluştuğunu ve AdventureWorks => Programmability=>Stored Procedures altında Usp_GetProductList saklı yordamının da oluştuğunu görüyoruz.

Resim-11

Saklı yordamı çalıştırıyor ve Results penceresinde ürünlerin listesine ulaşmış oluyoruz.

Resim-12

CLR İle Stored Procedure – Parametre Kullanımı

Bir önceki örneğimizde ürünlerimizin listesini veren bir Assembly geliştirmiştik. Şimdi CLR ile geliştirdiğimiz saklı yordamda parametre kullanımına örnek olması açısından bir saklı yordam daha ekleyelim. Bu saklı yordam, bize ürünlerimizin parametrede verilen renk filtresine göre listelenmesini sağlayacak. Projeye sağ tıklayıp Add=> New Item yolu ile yeni bir SQL CRL C# Stored Procedure ekliyoruz. Ben ismini Usp_GetProductListByColor olarak verdim.

CLR ile geliştirilen Stored Procedure parametre ekleme işlemi, .Net ile metoda parametre ekleme işlemi ile aynı işlemden ibarettir. Aşağıdaki kodları Usp_GetProductListByColor.cs kod saydama ekliyorum.

public
static
void Usp_GetProductListByColor(string Color)

{


using (SqlConnection con = new
SqlConnection(“context connection=true”))

{


if (con.State != ConnectionState.Open)

{

con.Open();

}


using (SqlCommand cmd = new
SqlCommand(“SELECT * FROM Production.Product WHERE Color=@Color”, con))

{

cmd.Parameters.AddWithValue(“@Color”, Color);


SqlContext.Pipe.Send(cmd.ExecuteReader());

}

}

}

Resim-13

Tekrar projemi Publish yaptıktan sonra oluşmuş olan Stored Procedure’e renk bilgisi vererek çalıştırıyorum.

Resim-14

CLR ile parametreli bir şekilde Stored Procedure ( Saklı Yordam ) oluşturup çalıştırmış olduk.

CLR İle Stored Procedure – Dynamic ResultSet

CLR ile oluşturmuş olduğumuz Stored Procedure’ lerimizde ihtiyacımıza göre kendi dinamik verilerimizi de oluşturabiliriz. Çok kullanıma sahip olmayan bir durum olmasına rağmen bağzı projelerde ihtiyaç duyabilirsiniz.

CLR ile on satır iki sütunlu bir Resultset ( sonuç kümesi ) oluşturalım. Tekrar projemize sağ tıklayıp Add => New Item yolu ile yeni bir SQL CRL C# Stored Procedure ekliyoruz. Ben ismini Usp_GetDynamicResultSet olarak verdim.

public
static
void Usp_GetDynamicResultSet()

{


//meta bilgilerini oluşturmak için


SqlMetaData[] md = new
SqlMetaData[2];

md[0] = new
SqlMetaData(“intIDColumn”, SqlDbType.Int);

md[1] = new
SqlMetaData(“stringProductColumn”, SqlDbType.VarChar, 100);


//Kayıtlarımızı tutmak için


SqlDataRecord dr = new
SqlDataRecord(md);


SqlContext.Pipe.SendResultsStart(dr);


for (int i = 1; i <= 10; i++)

{

dr.SetSqlInt32(0, i);

dr.SetSqlString(1, “Ürun Adı “ + i.ToString());


SqlContext.Pipe.SendResultsRow(dr);

}


SqlContext.Pipe.SendResultsEnd();

}

Resim-15

Kodları ekledikten sonra projeyi tekrar Publish yapıyor ve SQL Server Management Studio‘da yeni bir sorgu ekranı açıp oluşturmuş olduğum Stored Procedure ‘ü çalıştırıyorum.

Resim-16

Dinamik olarak oluşturduğumu Resultset’ i ( Sonuç Kümesi) listelemiş olduk.

Publish Save Profile

Her Publish sırasında tekrar tekrar Target Database Connection bilgilerini girmek istemiyorsanız, Connection ( Bağlantı ) bilgilerini oluşturduktan sonra Publish Database ekranında bulunan Create Profile düğmesi ile veri tabanı bağlantı bilgilerinizi kaydetmeniz yeterli olacaktır. Daha sonraki Publish işlemlerinizde Publish Database ekranındayken Load Profile ile daha önceki kaydetmiş olduğuz bağlantı bilgisini yükleyip hızlıca Publish işlemini gerçekleştirebilirsiniz.

Resim-17

Profili yüklemek için;

Resim-18

CLR ile Scalar – Valued Function

CLR ile Scalar – Valued Function (Sayısal değerli fonksiyon) oluşturalım. Yapacağımız örnekte dışarıdan renk parametresi alan ve o renge ait kaç tane ürün olduğu bilgisini veren bir Scalar fonksiyon oluşturalım.

Oluşturmuş olduğumuz projeye sağ tıklayıp Add => New Item yolu ile yeni bir SQL CRL C# User Defined Function ekliyoruz. Ben ismini UDF_CountProductByColor olarak verdim.

[Microsoft.SqlServer.Server.SqlFunction(DataAccess=DataAccessKind.Read)]


public
static
int UDFCountProductByColor(string Color)

{


int count = 0;


using (SqlConnection con=new
SqlConnection(“context connection=true”))

{


if (con.State != ConnectionState.Open) con.Open();


using (SqlCommand cmd = new
SqlCommand(“SELECT COUNT(*) FROM Production.Product WHERE COLOR=@Color”, con))

{

cmd.Parameters.AddWithValue(“@Color”, Color);

count =(int)cmd.ExecuteScalar();

}

}


return count;

}


Resim-19

Projeyi Publish yaptıktan sonra fonksiyonu çağırdığınızda eğer aşağıdaki hata ile karşılaşırsanız;


Resim-20

Metodumuzun üstündeki kodu aşağıdaki gibi revize etmeyi unutmayınız;

[Microsoft.SqlServer.Server.SqlFunction(DataAccess=DataAccessKind.Read)]

Publish işleminden sonra oluşturmuş olduğumuz fonksiyonumuzu çağıralım;

Resim-21

CLR ile Table – Valued Function

CLR ile Table – Valued Function (Tablo değerli fonksiyon) oluşturalım. Yapacağımız örnekte fonksiyonumuz bize bir tablo oluşturup bu tabloyu bize döndürmektedir. Generic List kullanarak myProduct sınıfıma değerler ekleyip, bu değerler ile Table-Valued Function oluşturdum.

public
partial
class
UserDefinedFunctions

{

[SqlFunction(DataAccess = DataAccessKind.Read, FillRowMethodName = “FillRowCustomTable”, TableDefinition = “ID int,Name nvarchar(255)”)]


public
static
IEnumerable GetProducts()

{


List<myProduct> entity = new
List<myProduct>();

entity.Add(new
myProduct { ID = 101, Name = “Computer” });

entity.Add(new
myProduct { ID = 102, Name = “Smart Phone” });

entity.Add(new
myProduct { ID = 103, Name = “Laptop” });

entity.Add(new
myProduct { ID = 104, Name = “Tablet” });


return entity;

}


public
static
void FillRowCustomTable(object resultObj, out
SqlInt32 ID, out
SqlString Name)

{


myProduct myResult = (myProduct)resultObj;

ID = myResult.ID;

Name = myResult.Name;

}


public
class
myProduct

{


public
int ID { get; set; }


public
string Name { get; set; }

}

}

Resim-22

Projeyi derleyip Publish yaptıktan sonra Management Studio‘ da oluşturmuş olduğumuz fonksiyonumuzu çağırıyoruz.

Resim-23

Bu makalemizde, SQL Server üzerinde Assembly geliştirmesini, .Net platformu ile nasıl CLR geliştirmesi yapacağımızı incelemiş olduk. Farklı örneklerle konuyu pekiştirmeye çalıştım. .NET çatısı altında bulunan C#.Net yazılım geliştirme dili ile geliştirmiş olduğumuz kod parçacıklarını SQL Server üzerinde nasıl kullanabileceğimizi öğrenmiş olduk. Faydalı olması dileğiyle.

Bu konuyla ilgili sorularınızı  alt kısımda bulunan yorumlar alanını kullanarak sorabilirsiniz.

Referanslar

www.mshowto.org

TAGs: SQL Server, Assembly, CLR, .Net ile CLR, Table – Valued Function, Skaler – Valued Function, Dynamic Resultset, SQL Server Database Project, Visual Studio, Net Framework, MSIL, JIT, ECONOJIT, JIT , PREJIT

Bu İçeriğe Tepkin Ne Oldu?
  • 4
    harika_
    Harika!!
  • 0
    be_enmedim
    Beğenmedim
  • 0
    _ok_iyi
    Çok iyi
  • 0
    sevdim_
    Sevdim!
  • 0
    bilemedim_
    Bilemedim!
  • 0
    olmad_
    Olmadı!
  • 0
    k_zd_m_
    Kızdım!

Selçuk Üniversitesi Bilgisayar programcılığı bölümünden mezun olduktan sonra birçok firmada Yazılım, İş zekası ve Veritabanı Uzmanı olarak çalıştım. Şu an Türkiye’nin en büyük şirketlerinden biri olan Doğan Online’da Veritabanı Yöneticisi olarak çalışıyorum.

Yazarın Profili

Bültenimize Katılın

Tıklayın, üyemiz olun ve yeni güncellemelerden haberdar olan ilk kişi siz olun.

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir