I need to add line break character to a long string (word wrapping) so that each line should not contain more than 20 symbols, divided by words (with space symbol).
For example:
input: 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
output: 1 2 3 4 5 6 7 8 9 0 \n1 2 3 4 5 6 7 8 9 0 \n1 2 3 4 5 6 7 8 9 0 \n 1 2 3
Here is my query which is almost done.
But something is wrong with it.
For input: 111111 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
It gives me wrong result: 111111 2 3 4 5 6 7 8 9 0 1 \n2 3 4 5 6 7 8 9 0 1 \n2 3 4 5 6 7 8 9 0 1 \n2 3
As you can see first line is more than 20 symbols.
I can't find how to tune it.
Can you suggest me how to enhance my query?
;WITH ct AS (
SELECT
'1111111 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0' AS VAL,
20 AS MAX_LINE
),PT AS (
SELECT
VAL,
1 AS LVL,
0 AS LEN_LINE,
0 AS LEN_PART,
MAX_LINE,
VAL + ' ' AS REST,
CAST('' AS NVARCHAR(300)) AS LINES
FROM CT
UNION ALL
SELECT
S.VAL,
S.LVL,
CASE WHEN S.LEN_LINE + S.LEN_PART > S.MAX_LINE THEN S.LEN_PART ELSE S.LEN_LINE + S.LEN_PART END AS LEN_LINE,
S.LEN_PART,
S.MAX_LINE,
S.REST,
CAST(S.LINES + CASE WHEN S.LEN_LINE + S.LEN_PART > S.MAX_LINE THEN '\n' ELSE '' END AS NVARCHAR(300)) AS LINES
FROM (
SELECT
S.*,
CHARINDEX(' ', S.REST) AS LEN_PART
FROM (
SELECT
P.VAL,
P.LVL + 1 AS LVL,
P.LEN_LINE,
P.MAX_LINE,
RIGHT(P.REST, LEN(P.REST + '_')-1-CHARINDEX(' ', P.REST)) AS REST,
P.LINES + LEFT(P.REST, CHARINDEX(' ', P.REST)) AS LINES
FROM PT AS P
WHERE CHARINDEX(' ', P.REST) > 0
) AS S
) AS S
)
--uncomment for debug
--SELECT * FROM PT
SELECT S.*
FROM (
SELECT
P.VAL,
P.LVL,
P.LEN_LINE,
P.LEN_PART,
P.REST,
CASE WHEN RIGHT(P.LINES, 2) = '\n' THEN LEFT(P.LINES, LEN(P.LINES + '_')-1-2) ELSE P.LINES END AS LINES,
ROW_NUMBER() OVER(PARTITION BY P.VAL ORDER BY P.LVL DESC) AS N
FROM PT AS P
) AS S
WHERE S.N = 1