ОК, я везде искал правильный синтаксис. Скажем, у меня есть веревка неизвестной длины, например: «Быстрая коричневая лиса перепрыгивает через ленивую собаку. Быстрая коричневая лиса прыгает через ленивую собаку. Быстрая коричневая лиса прыгает через ленивую собаку. Быстрая коричневая лиса прыгает через ленивую собаку. Быстрая коричневая лиса перепрыгивает через ленивую собаку. '
Мне нужно разбить ее на куски по 35 символов каждый: «Быстрая коричневая лиса перепрыгивает через пробел» - это разделитель.
правила таковы:
1 - каждый фрагмент длиной не более 35 символов
2 - НЕ разбивать слова.
2.1 - если общая длина больше чем 35, go назад, пока не найдете первое пространство, где длина меньше 35 и вырезать его там.
3 - набор результатов должен возвращать таблицу с 5 значениями (состоящими из кусочков строк) и номером строки, указывающим результат более чем одной записи, если это необходимо. (см. таблицу ниже)
, то есть если строка делится на 5 35 блоков символов, одна запись возвращает любые избыточные разливы в большее количество строк в наборе 5
________________________________________________________________________________________________________________________________________________________________________________|
|level | Val1 |Val2 | Val3 | Val4 | Val5 |
________________________________________________________________________________________________________________________________________________________________________________|
| 1 |The quick brown fox jumps over the | lazy dog. The quick brown fox | jumps over the lazy dog. The | quick brown fox jumps over the | lazy dog. The quick brown fox |
| 2 | jumps over the lazy dog. The | quick brown fox jumps over the| lazy dog. |NULL | NULL |
________________________________________________________________________________________________________________________________________________________________________________|
Я нашел здесь некоторый код такая работа, но я не могу получить результат, ограниченный 35 кусками символов
, что он делает: получить количество разделителей в строке (количество пробелов), чем разделить все, используя CTE, в таблицу. чем объединить все обратно. но в "Splitvalues" cte, если я разбиваю mainLevel на чанки по 5, он работает, но объединяется не по длине, а по группе из 5, и я все еще не понимаю, как развернуть результат в столбец 6, как описано.
DECLARE @ColumnLen INT = 35
,@BNotAllowNullinValue1 BIT = 1
,@Delim VARCHAR(5) = SPACE(1)
,@DelimCount INT
,@OriginalStr NVARCHAR(MAX) = 'The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.'
,@ReturnColumnCount INT = 5
SET @OriginalStr = @OriginalStr + @Delim
SET @DelimCount = ((LEN(@OriginalStr + '|')-1) - (LEN(REPLACE(@OriginalStr + '|',@Delim,''))-1)) / LEN(LTRIM(RTRIM(@Delim)) + '|')
---- test data
;WITH Splitvalues(SplitValue ,MainLevel ,ProcessLevel,LastPos,Original)
AS (SELECT TOP 1 LTRIM(RTRIM(SUBSTRING(@OriginalStr,1,ABS(CHARINDEX(@Delim,@OriginalStr,1)))))
,1 as MainLevel
,1 as ProcessLevel
,CHARINDEX(@Delim,@OriginalStr,1 + 1) AS LastPos
,@OriginalStr
UNION ALL
SELECT LTRIM(RTRIM(SUBSTRING(@OriginalStr,LastPos + 1,ABS((CHARINDEX(@Delim,@OriginalStr,LastPos + 1) - LastPos)))))
,CASE (ProcessLevel % 5) WHEN 0 THEN MainLevel +1 ELSE MainLevel END as MainLevel
,ProcessLevel + 1 as ProcessLevel
,CHARINDEX(@Delim,@OriginalStr,LastPos + 1) AS LastPos
,@OriginalStr
FROM Splitvalues
WHERE ProcessLevel <= @DelimCount
AND ISNULL(LTRIM(RTRIM(SUBSTRING(@OriginalStr,LastPos + 1,ABS((CHARINDEX(@Delim,@OriginalStr,LastPos + 1) - LastPos))))),'') <> '')
---- actual query;
,cte(MainLevel,ProcessLevel,combined,rn)
AS (SELECT MainLevel,ProcessLevel,Splitvalue ,rn = ROW_NUMBER() OVER(PARTITION BY MainLevel ORDER BY MainLevel,ProcessLevel)FROM Splitvalues)
,cte2(MainLevel,ProcessLevel ,finalstatus ,rn)
AS (SELECT MainLevel,cte.ProcessLevel ,CONVERT(VARCHAR(MAX),combined) ,1 FROM cte WHERE rn = 1
UNION ALL
SELECT cte2.MainLevel,cte2.ProcessLevel +1 ,CONVERT(VARCHAR(MAX),cte2.finalstatus + @Delim + cte.combined+ @Delim )
,cte2.rn + 1
FROM cte2
INNER JOIN cte ON cte.MainLevel = cte2.MainLevel AND cte.rn = cte2.rn + 1
)
SELECT MainLevel,MAX(finalstatus),LEN(MAX(finalstatus)+'|')
FROM cte2
GROUP BY MainLevel
спасибо за помощь.