16 Temmuz 2013 Salı

SQL String Split - Bir stringi bir karaktere göre parçalamak


Pek çok sitede bulunabilecek bir kullanım olduğunun farkındayım ama yazmazsam hemmen unuturum.. :)

Üzerinde çalıştığım sistemde kullanıcılar domain kullanıcı ve form kullanıcısı olarak iki farklı şekilde sisteme kaydediliyor. Her domain kullanıcısının bir form kullanıcısı var ancak her form kullanıcısının bir domain kullanıcısı yok. Bana lazım olan ise domain kullanıcısı olan form kullanıcıları.. bu iki kullanımın da tek ortak yönü isimleri.. Domain kullanıcısı Firma\Monolâra şeklindeyken form kullanıcısı Monolâra şeklinde.. bu durumda isimlerden kontrol etmekten başka çarem yok gibi görünüyor :) 

İşte de şöyle yaptım;

SELECT DBO.CF_ASSET_NAME(GUID_ASSET_Y) AS Y,
FROM VDB_ASSET_RELATIONS
WHERE PRM1=1 AND GUID_ASSET_X IN (SELECT GUID_ASSET_Y
                                  FROM VDB_ASSET_RELATIONS
                                  WHERE GUID_ASSET_X='880E69C9-8292-4B62-B718-4229B624EBCE'
                                   AND GUID_ASSET_Y IN ('AF8FD4D3-9EA1-4F3E-8271-1CF47C48CF23','9ABBC878-F195-431E-8093-7F449F2BA83C')
                                        AND PRM1=1
                                  )
       AND PRM2='Kullanici.Yonetimi.Kullanici'
       AND DBO.CF_ASSET_NAME(GUID_ASSET_Y) IN
       (
             SELECT LTRIM(PARSENAME(REPLACE(PRM0, '\', '.'), 1)) AS ISIMLER
             FROM VDB_ASSETS
             WHERE GUID_PARENT='D5610D87-C220-477F-BA14-009EAB24EBE4'
           AND PRM1 = 1
           AND PRM0 LIKE '%\%'
       )   
----------------------------ya da----------------------
SELECT DBO.CF_ASSET_NAME(GUID_ASSET_Y) AS Y,
FROM VDB_ASSET_RELATIONS
WHERE PRM1=1 AND GUID_ASSET_X IN (SELECT GUID_ASSET_Y
                                  FROM VDB_ASSET_RELATIONS
                                  WHERE GUID_ASSET_X='880E69C9-8292-4B62-B718-4229B624EBCE'
                                   AND GUID_ASSET_Y IN ('AF8FD4D3-9EA1-4F3E-8271-1CF47C48CF23','9ABBC878-F195-431E-8093-7F449F2BA83C')
                                        AND PRM1=1
                                  )
       AND PRM2='Kullanici.Yonetimi.Kullanici'
       AND DBO.CF_ASSET_NAME(GUID_ASSET_Y) IN
       (
             SELECT SUBSTRING(PRM0,CHARINDEX('\',PRM0)+1,len(PRM0)) AS ISIMLER
             FROM VDB_ASSETS
             WHERE GUID_PARENT='D5610D87-C220-477F-BA14-009EAB24EBE4'
           AND PRM1 = 1
           AND PRM0 LIKE '%\%'
       )     

Aslında tablo yapılarımıza göre gitmem gereken yol yukarıdakiydi ama sorgusu 1 dk 13 sn'lik bir sonuç dönünce başka bir yoldan gittim mecburen.. :)


SELECT PRM0
FROM VDB_ASSETS
WHERE
PRM1 = 1
AND PRM0 IN(SELECT LTRIM(RTRIM(PARSENAME(REPLACE(PRM0, '\', '.'), 1))) AS ISIMLER
            FROM VDB_ASSETS
            WHERE GUID_PARENT='D5610D87-C220-477F-BA14-009EAB24EBE4'
                  AND PRM1 = 1
                  AND PRM0 LIKE '%\%'
            )
ORDER BY PRM0

------------------ya da--------------------
SELECT PRM0
FROM VDB_ASSETS
WHERE
PRM1 = 1
AND PRM0 IN(SELECT SUBSTRING(PRM0,CHARINDEX('\',PRM0)+1,len(PRM0))  AS ISIMLER
FROM VDB_ASSETS
WHERE GUID_PARENT='D5610D87-C220-477F-BA14-009EAB24EBE4'
AND PRM1 = 1
AND PRM0 LIKE '%\%'
            )
ORDER BY PRM0


Bu sorgumda bir sorun yok şimdilik.. Olur da şirket çok büyürse küçük bir ihtimal sorun çıkar onun da yakın gelecekte olacağını zannetmiyorum :)

Başlığımda bahsettiğim olayı sağlayan kodlar;

SUBSTRING(PRM0,CHARINDEX('\',PRM0)+1,len(PRM0))
(PARSENAME(REPLACE(PRM0, '\', '.'), 1))
\ karakterinden sonrasını yani Firma\Monolâra nın Monolâra kısmını alır.. 

Yok ben Monolâra yı değil Firma kısmını almak istiyorum diyorsanız kodlarda ufak değişiklikler yeterli olacak;

SUBSTRING(PRM0,0,CHARINDEX('\',PRM0))
(PARSENAME(REPLACE(PRM0, '\', '.'), 2))
\ karakterinden öncesini alır, yani Firma yı..

Farklı olarak, LTRIM, RTRIM baştaki ve sondaki boşlukları atmaya yarıyormuş, artistlik olsun diye kullandım onları da. :P

Şimdi bunları LINQ da nasıl yapıcam ona bakmam lazım.. Müsâdenizle efendiler .. ;)

Hiç yorum yok:

Yorum Gönder