CLR User Defined Functions Part III

by Volem November 23, 2010 10:08

User defined fonksiyonlarin 3. yazisini biraz geciktirdim malesef.. Isler arti bayram tatili araya girince elde olmayan sebepler olustu. Bugun size clr ile tanimlayabileceginiz aggregate fonksiyonlardan bahsedecegim. Eger daha once goz atmadiysaniz yazimin I. ve II. kisimlarini okumanizi tavsiye ederim. Daha onceki kisimlardan da hatirlayacaginiz uzere kullanici tanimli fonksiyonlar tanimlamak icin belirli kurallara uymamiz gerekiyor. Bir aggregate fonksiyon tanimlamak icin oncelikli olarak sinifinizin IBinarySerialize interface'ini implement etmesi gerekiyor. Bu interface bize iki adet metod sunuyor; Read ve Write.. Bu metodlar SQLServer ile CLR arasindaki asil veri akisini saglayan metodlardir. Ornekten de anlasilacagi uzere olusan veriyi sqlserver'a donduren veya sqlserverdan okuyan metodlardir. Bunun disinda sinifinizin 4 adet daha metod icermesi gerekiyor. Bu metodlar; Init, Accumulate, Merge ve Terminate..(Sizlere tavsiyem verdigim ornegi derlerken metodlardan birini cikarin ve bu sekilde olusan assemblyi sql server'a register etmeye calisin.. Zaten alacaginiz hata sizi yonlendirecektir.)

Sirasiyla metodlari anlatmadan once ornek kodu asagida veriyorum. Bu kod ile grupladiginiz bir kolondaki degerleri virgullerle ayirip baska bir kolonda yazabiliyorsunuz. MySQL'de built-in olan concat aslinda tam olarak concat_ws (concat with seperator) aggregate fonksiyonunun implementasyonu oluyor bu ornek. Bu arada MSSQL (T-SQL) built-in aggregate fonksiyonlara bakmak isterseniz lutfen buraya

using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.IO;
using System.Text;

[Serializable]
[SqlUserDefinedAggregate(
Format.UserDefined,
IsInvariantToNulls = true,
IsInvariantToDuplicates = false,
IsInvariantToOrder = false,
MaxByteSize = 8000)
]
public class Concatenate : IBinarySerialize
{
private StringBuilder intermediateResult;

public void Init()
{
this.intermediateResult = new StringBuilder();
}

public void Accumulate(SqlString value)
{
if (value.IsNull)
{
return;
}

this.intermediateResult.Append(value.Value).Append(',');
}

public void Merge(Concatenate other)
{
this.intermediateResult.Append(other.intermediateResult);
}

public SqlString Terminate()
{
string output = string.Empty;
if (this.intermediateResult != null
&& this.intermediateResult.Length > 0)
{
output = this.intermediateResult.ToString(0, this.intermediateResult.Length - 1);
}

return new SqlString(output);
}

public void Read(BinaryReader r)
{
intermediateResult = new StringBuilder(r.ReadString());
}

public void Write(BinaryWriter w)
{
w.Write(this.intermediateResult.ToString());
}
}

Sirasiyla gerceklememiz gereken metodlara bakalim. Aslinda bir constructor olarak dusunebileceginiz Init metodu ile sinifiniz icerisinde yer alan degiskenlerin ilk degerlerini verebilirsiniz. Accumulate metodu ise asil concat isleminin yapildigi yer. Kodtan da anlasilacagi uzere bos olmayan degerleri virgulle ayirarak output'a yaziyoruz. Terminate metodunda ise en son yapmak istediginiz islemleri yapabilirsiniz, ornegimizde en sondaki virgulu kaldirma islemi yapiliyor. Henuz bahsetmedigim merge metodu da iceriginden de anlasilacagi gibi birden fazla concatenate fonksiyonunun birbiri ile anlasmasini saglayacak metodtur.

Son olarak bir user defined aggregate tanimlamak icin sinifiniza 2 adet attribute(ozellik) eklemeniz gerekiyor. Bunlardan birincisi Serializable, digeri ise SqlUserDefinedAggregate. Burada SqlUserDefinedAggregate ozelligi icin bazi named parametre tanimlari goruyorsunuz. Zaten isimleri icerigini anlatiyor ancak diger parametre ve detaylar icin buraya bir goz atabilirsiniz.

Gelelim bu tanimladigimiz sinifimizi nasil SQL server'a tanitacagimiza.. Daha onceki CLRvsSQLServer yazilarimi okuduysaniz, yine oradakine benzer bir tanimlama kullanacagiz.


CREATE ASSEMBLY ClrCode FROM '<DLL_Path>'
GO
CREATE AGGREGATE Concatenate (@input nvarchar(200)) RETURNS nvarchar(max)
EXTERNAL NAME ClrCode.[ArticleCodes.Concatenate]

Herkeslere kolay gelsin...

 

Tags: , ,

C# | SQL

Add comment




  Country flag
Click to change captcha
biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen | Modified by Volem

RSS
View Volkan Nazmi Metin's profile on LinkedIn

RevolverMap

Son Eklenen Yazılar

Yazar Hakkında

Sosyal, evli, çocuklu, karısını ve kızını çok seven, gezmeyi seven, spor yapmak isteyen bir mühendis