I'm reviving this as I found Nathan Skerl's script extremely helpful, thanks Nathan!
I modified it into an UDF and made a bit more flexible for what I needed it for:
CREATE FUNCTION [dbo].[fnSplitStringIntoChunks]
( @Txt nvarchar(max),@Delimitator char(1), @Limit int, @ChunkToReturn int)
RETURNS @SplitChunks table ( txtChunk nvarchar(max) )
AS
--------------------fnSplitStringIntoChunks ----------------------------------
--(adapted from CTE code by Nathan Skerl: http://ask.sqlservercentral.com/questions/23224/function-for-splitting-sentence.html)
--Splits a string into chunks of the maximum specified length without splitting up words ie. will only split at the specified delimitator.
--Usage: fnSplitStringIntoChunks(StringToSplit, Delimitator, MaxChunkLength, ChunkToReturn)
--Set ChunkToReturn to = 0 to return all chunks, or use it to specify which chunk to return.
--Examples:
--Select * from dbo.fnSplitStringIntoChunks('This is a long sentence and I want to split it into multiple sentences of 50 characters each with out splitting a word into multiple lines',' ', 50, 0)
--Result:
---------------------------------------------------
--This is a long sentence and I want to split it
--into multiple sentences of 50 characters each
--with out splitting a word into multiple lines
---------------------------------------------------
--Select * from dbo.fnSplitStringIntoChunks('This is a long sentence and I want to split it into multiple sentences of 50 characters each with out splitting a word into multiple lines',' ', 50, 2)
--Result:
---------------------------------------------------
--into multiple sentences of 50 characters each
---------------------------------------------------
--Select * from dbo.fnSplitStringIntoChunks('This is a long sentence| and I want to| split it| into multiple| sentences of 50 characters each with| out splitting a word| into multiple lines','|', 50, 0)
--Result:
---------------------------------------------------
--This is a long sentence| and I want to| split it
-- into multiple
-- sentences of 50 characters each with
-- out splitting a word| into multiple lines
---------------------------------------------------
--Example usage within another select:
----- Select LongStreetAddressToSplit, addressLine1.txtChunk, addressLine2.txtChunk, addressLine3.txtChunk from tmpAddresses
----- OUTER APPLY dbo.fnSplitStringIntoChunks(LongStreetAddressToSplit, ' ',50, 1) as addressLine1
----- OUTER APPLY dbo.fnSplitStringIntoChunks(LongStreetAddressToSplit, ' ',50, 2) as addressLine2
----- OUTER APPLY dbo.fnSplitStringIntoChunks(LongStreetAddressToSplit, ' ',50, 3) as addressLine3
--(In this example we expect the majority of LongStreetAddressToSplit values to split nicely into 3 chunks (by looking at a sample of the data),
-- but it would be prudent to check if any Addresses had to be split into a 4th chunk:)
----- Select LongStreetAddressToSplit, addressLine4.txtChunk from tmpAddresses
----- OUTER APPLY dbo.fnSplitStringIntoChunks(LongStreetAddressToSplit, ' ', 50, 4) as addressLine4
----- where addressLine1.txtChunk is not null
-----------------------------------------------------------------------------
BEGIN
DECLARE @chunkTable table (txtChunk nvarchar(max), chunkID int IDENTITY(1,1))
;with cte_DoIt
as (
select substring(@Txt, 0, ((@Limit+1)-charindex(@Delimitator, reverse(left(@Txt + @Delimitator,@Limit))))) [Chunk],
stuff(@Txt, 1, ((@Limit+1)-charindex(@Delimitator, reverse(left(@Txt + @Delimitator,@Limit)))), '') [Swap]
union all
select substring(Swap, 0, (@Limit+1) - charindex(@Delimitator, reverse(left(Swap + @Delimitator, @Limit)))),
stuff(Swap, 1, ((@Limit+1)-charindex(@Delimitator,reverse(left(Swap + @Delimitator,@Limit)))), '')
from cte_DoIt
where len(Swap) > 0
)
Insert @chunkTable
select Chunk
from cte_DoIt
Insert @SplitChunks
select txtChunk
from @chunkTable
where 1=1
and chunkID = Case @ChunkToReturn When 0 Then chunkID Else @ChunkToReturn End
RETURN
END;
GO
↧