Funkcija za splitovanje stringova – Tally
Objavljeno: 27-11-2014 | Autor: Nenad Živković | Kategorija: Skriptovi
0
Preuzmi: SQLKefalo_SplitterFunkcija_Tally.sql
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
-- **************************************************************** -- www.sql-kefalo.net -- **************************************************************** -- Datum: 16.11.2014 -- Opis: Funkcija za splitovanje stringa koriscenjem inline tabela sa brojevima -- Clanak: http://www.sql-kefalo.net/2014/11/funkcije-za-splitovanje-stringova -- **************************************************************** CREATE FUNCTION [dbo].[udfKefalo_Splitter_Tally] ( @UlazniString NVARCHAR(MAX) , @Delimiter NVARCHAR(255) ) RETURNS @rv TABLE ( RedniBroj INT IDENTITY(1,1) , Element NVARCHAR(4000) ) AS BEGIN IF @UlazniString IS NULL RETURN ; IF @Delimiter IS NULL SET @Delimiter = ','; WITH C10 (N) AS ( --Kreiranje prvih 10 redova sa jedinicama SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ) ,C100 (N) AS ( --Umnozavanje prethodnog cte za kreiranje 100 redova SELECT 1 FROM C10 a CROSS JOIN C10 b ) ,C10K (N) AS ( --10000 redova SELECT 1 FROM C100 a CROSS JOIN C100 b ) ,C1M (N) AS ( --Milion redova, sto je maksimum znakova za koji ce funkcija raditi SELECT 1 FROM C10K a CROSS JOIN C100 b ) ,CTE_Brojevi (N) AS ( --Racunanje duzine ulaznog stringa i priprema rednih brojeva od 1 do duzine --Cime se sprecava da se stvarno kreira 1 milion redova vec samo neophodan broj SELECT TOP (COALESCE(DATALENGTH(@UlazniString)/2,0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM C1M ) ,CTE_Start (Pocetak) AS ( --Odredjivanje pocetnih mesta gde se nalaze elementi (lokacije delimitera + duzina delimitera) SELECT 1 UNION ALL SELECT t.N+COALESCE(DATALENGTH(@Delimiter)/2,0) FROM CTE_Brojevi t WHERE SUBSTRING(@UlazniString,t.N,COALESCE(DATALENGTH(@Delimiter)/2,0)) = @Delimiter ) ,CTE_Duzina (Pocetak, Duzina) AS ( --Prepisuju se pocetne lokacije i racunaju duzine svakog elementa SELECT s.Pocetak , ISNULL(NULLIF(CHARINDEX(@Delimiter,@UlazniString,s.Pocetak),0)-s.Pocetak,COALESCE(DATALENGTH(@UlazniString)/2,0)) FROM CTE_Start s ) INSERT INTO @rv (Element) --Krajnji rezultat se smesta u return tabelu gde dobija i redni broj SELECT LTRIM(SUBSTRING(@UlazniString, d.Pocetak, d.Duzina)) FROM CTE_Duzina d; RETURN; END; GO |