TSQL Split Islemi (Metni Parçalamak)

Bazen SQL tablolarinda bazi veriler text olarak birlestirilerek yan yana tek bir kolonda tutulur. Bu kolonlar ile islem yapacaginiz zaman belirli bir ayraca göre bu metni parçalamamiz gerekir. Malesef TSQL de bunu yapabilecegimiz hazir bir fonksiyon bulunmuyor.

Bir metni parçalamak için asagida sorgusunu verdigim fonksiyonu kullanabilirsiniz. Bu fonksiyonu kendi veritabaninizda olusturarak sorgularinizda çagirabilirsiniz. .

CREATE FUNCTION dbo.MetinParcala
(
   @Metin NVARCHAR(MAX),
   @Ayrac NVARCHAR(MAX)
)
RETURNS @AyrismisTablo TABLE
(
   ID INT IDENTITY(1,1),
   AyrilmisMetin NVARCHAR(MAX)
)
AS
BEGIN
   DECLARE @Sayac INT
   SET @Sayac = 1
   DECLARE @Index INT
   SET @Index = CHARINDEX(@Ayrac,@Metin)
   WHILE (@Index>0)
   BEGIN
      INSERT INTO @AyrismisTablo (AyrilmisMetin)
      SELECT
      AyrilmisMetin = LTRIM(RTRIM(SUBSTRING(@Metin, 1, @Index - 1)))       
      SET @Metin = SUBSTRING(@Metin,
      @Index + DATALENGTH(@Ayrac) / 2,
      LEN(@Metin))        SET @Sayac = @Sayac + 1
      SET @Index = CHARINDEX(@Ayrac, @Metin)
   END

   INSERT INTO @AyrismisTablo (AyrilmisMetin)
   SELECT AyrilmisMetin = LTRIM(RTRIM(@Metin))
   RETURN
END

Sorguyu inceleyecek olursaniz ilk olarak ayrac karakterini metin içinde aratiyoruz. Eger bulabilirsek bu indexe kadar olan metni alip tabloya atiyoruz. Ardindan metnin bu indexden bir sonraki karaktere kadar olan kismi çikariyoruz ve aramaya devam ediyoruz.

.

Yukaridaki sql scriptini çalistirdiginizda veritabaniniza MetinParcala isimli bir fonksiyon olusacak. Bu fonksiyonu asagidaki gibi çagirarak kullanabilirsiniz.

select * from dbo.MetinParcala('www.yazilimmutfagi.com','.')

Yukaridaki sorguyu çalistirdiginiz zaman www.yazilimmutfagi.com metnini “.” karakterlerine göre parçalayip asagidaki tabloyu döndürecektir.

ID AyrilmisMetin
1 www
2 yazilimmutfagi
3 com

Umarim isinize yarayacak bir fonksiyon olmustur.

.

17 thoughts on “TSQL Split Islemi (Metni Parçalamak)

  1. Merhabalar,

    Verdiğiniz örnek için çok teşekkür ederim. Fonksiyon çok kullanışlı lakin bunları alt alta değilde yan yana dizilimde getirme imkanımız var mıdır?
  2. Haklisin Cursor kullanii performans açisindan tavsiye edilmez. tek sorgua yapmak için ben biraz daha deneme yaparim. bi çözum bulursam paylasirim.

  3.  Yardimlariniz için çok tesekkür ederim ancak bu sekildeki tek bir sorgu kullanmak ile iki farkli sorgu kullanmak arasinda performans bakimindan ne gibi farklar olusur bilemiyorum. Bana bu konuda bir öneride bulunabilirseniz memnun olurum. Çünkü yukaridaki bir yöntemle ancak 10-15 kayit olan bir tabloda yerel bilgisayarimdaki basit sorgularda bile bilgisayar zorlaniyor gibi gözüküyor.

  4. Önceki yorumda kullandigim temp tablolarin create ve insertleri asagidaki gibi.

     

    create table #temp
    (
       Metin varchar(100),
    )
    create table #temp2
    (
       Metin varchar(20),
       AboneID int
    )
    insert into #temp(Metin) Values (‘1,2,3’),(‘4,5’)
    insert into #temp2(Metin,AboneID) values (‘1’,123),(‘2’,124),(‘3’,125),(‘4’,126),(‘5’,127)

  5. Istedigini anladim simdi Bu sekilde kullanman mumkun degil. ama cursor ile tablo1 deki her row için metin parcala fonksiyonu kullanilarak islem yapilabilir. Bunu için asagidaki gibi bir sorgu kullanmalisin

     

    declare @Metin varchar(100)
    declare cursor1 cursor for
          SELECT Metin from  #temp
    OPEN cursor1
    FETCH NEXT FROM cursor1
    INTO @Metin
    WHILE @@FETCH_STATUS = 0
    BEGIN
        select
        *
        from
        #temp2 t2 ,dbo.MetinParcala(@Metin,’,’) t3
        where t2.Metin = t3.AyrilmisMetin
        order by 1,2
      FETCH NEXT FROM cursor1 INTO @Metin
    END
    CLOSE cursor1
    DEALLOCATE cursor1

     

     

  6. Sayin msk. istegim asagidaki sorguyu kullanmak

    select * from tablo1,tablo2,tablo3,tablo4,dbo.MetinParcala(tablo4.alan,’,’) as t1 where tablo1.alan1 = tablo2.alan2 and tablo2.alan2 = tablo3.alan3 and tablo4.alan3 = t1.AyrilmisMetin

    sanal tablonun olusmasini istedigim alan tablo 4 deki bir sütun. Yukaridaki sorguyu çalistirdigimda 
     
    Msg 4104, Level 16, State 1, Line 1
    The multi-part identifier "tablo4.alan" could not be bound.
     
    hata iletisi aliyorum. tablo4.alan yerine ‘1,2,3,4,5’ gibi bir ifade girersem sorunsuz çalisiyor ancak ben bu degeri tablo4.alan sütununda tutuyorum.
     
  7. Hocam bu fonksiyonsonucu zaten bir tablo dondugu için sen bu tabloyu istedigin bir tablo ile join yapabilirsin.

    Sikinti nerede ?

    Örnegin :
    select * from
    dbo.MetinParcala(‘www.yazilimmutfagi.com’,’.’) t1
    inner join dbo.MetinParcala(‘www.yazilimmutfagi.com’,’.’)  t2 on t1.ID = t2.ID
    order by t1.AyrilmisMetin

     

     

     

  8. Mesajin yarisi görünmüyor. Devami söyle AyrilmisMetin  order by AyrilmisMetin asc" bu sorguyu çalistirmak istiyorum. Burada @AyrismisTablo yukaridaki fonksiyonun çalistirilmasiyla elde edilen tablo yardimlariniz ve önerileriniz için simdiden tesekkürler.

    Ben geçici olarak  where tablo1.id IN (select AyrilmisMetin from dbo.MetinParcala(tablo2.alan,’ayrac’)) gibi bir yöntemle isimi görmeye çalisiyorum ancak istedigim tam olarak bu degil.

  9. sayin Gezgin ilgilendiginiz için tesekkür ederim. Yukaridaki örnegi verilen tabloyu baska bir tablo ile birlestirip sorgulamak istiyorum. Yukaridaki tabloda fonksiyonun çalistirilmasiyla sanal bir tabloda AyrilmisMetin alani olusuyor. benim istegim gerçekteki bir tablodaki alanlari bu AyrilmisMetin alaniyla baglamak. yani    

    "select * from tablo1,tablo2,@AyrismisTablo where tablo1.id = tablo2.altid and tablo2.alan = @AyrismisTablo.

  10. Tam olarak yapmak istediginizi ve tablolariniz gönderirseniz yardimci olmaya çalisiyim.

  11.  Merhaba benim yapmak istedigim fonsiyon çiktisi oalrak olusturulan bu tabloyu inner join ile bir sorguda kullanmak. Bana bu konuda yardimci olabilir misiniz. Saygilarimla…

  12. merhaba öncelikle bu kaynaklari bize sagladginiz için tesekkür ederim…

    benim sorum söyle olucak . benim bir tablom var ve bu tabloda 3-4 tane sütun var beni ilgilendiren sütünlar su sekilde

     

    exp adli 1.sütün içerik tarzi: .metin…zfdsfsdfs..metin… ABC123456  metin..zxddfs… seklinde

    Kod adli 2.sütunum : iste buraya 1.sütündaki  sadece ‘ABC123456’ kisimlarini alip eklemem gerekiyo

     

     

    yardimci olursaniz sevinirim iyi günler..

     

Guests için bir cevap yazın Cevabı iptal et

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir