Разделить результаты запроса с длинными строками на несколько строк в T-SQL - PullRequest
0 голосов
/ 01 июля 2019

У меня есть таблица в MS SQL Server, которая содержит несколько полей TEXT, которые могут содержать очень длинные строки (от 0 символов до 100 000+ символов).

Я хотел бы создать представление (или сохраненный процесс, который заполняет таблицу отчетов), который подготавливает эти данные для экспорта в Excel, который имеет определенный допустимый предел символов на ячейку (32 767 символов).

Довольно просто написать запрос для усечения полей после определенного количества символов, но я хотел бы создать новые строки, содержащие текст, который будет обрезан.

Пример - строки 1, Col1 и Col3 содержат текст, который заключен в 2 строки.

ID   |   COL1   |   COL 2   |   COL 3   |
1       AAAAAA     BBBBBBB     CCCCCC
1       AAA                    CC
2       XX         YY          ZZ   

1 Ответ

2 голосов
/ 01 июля 2019

Вы можете попробовать что-то подобное:

A таблица макетов для имитации вашей проблемы

DECLARE @tbl TABLE(ID INT IDENTITY, LongString VARCHAR(1000));
INSERT INTO @tbl VALUES('blah')
                      ,('blah blah')  
                      ,('blah bleh blih bloh')
                      ,('blah bleh blih bloh bluuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh');

- Мы можем указать длину куска

DECLARE @Chunk INT=6;

SELECT t.ID
      ,A.Nmbr AS ChunkNmbr
      ,SUBSTRING(t.LongString,A.Nmbr*@Chunk+1,@Chunk) AS ChunkOfString
FROM @tbl t
CROSS APPLY(SELECT TOP(LEN(t.LongString)/@Chunk + 1) 
                   ROW_NUMBER() OVER(ORDER BY (SELECT NULL))-1 
            FROM master..spt_values) A(Nmbr);

Идея вкратце:

Мы используем трюк с APPLY и вычисленный TOP -класс. Источник master..spt_values - это обычная таблица с большим количеством строк. Нам не нужны значения, просто набор для вычисления текущего числа с использованием ROW_NUMBER(). APPLY будет называться строка за строкой . Это означает, что длинная строка создаст больше чисел, чем короткая.

Чтобы получить ваши чанки, я использую простой SUBSTRING(), где мы вычисляем начало каждого чанка путем довольно простого умножения.

ОБНОВЛЕНИЕ: более одного столбца за один раз

Попробуйте использовать этот подход для более чем одного столбца

DECLARE @tbl TABLE(ID INT IDENTITY, LongString1 VARCHAR(1000), LongString2 VARCHAR(1000));
INSERT INTO @tbl VALUES('blah','dsfafadafdsafdsafdsafsadfdsafdsafdsf')
                      ,('blah blah','afdsafdsafd')  
                      ,('blah bleh blih bloh','adfdsafdsafdfdsafdsafdafdsaasdfdsafdsafdsafdsafdsafsadfsadfdsafdsafdsafdsafdafdsafdsafadf')
                      ,('blah bleh blih bloh bluuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh','asdfdsaf');

DECLARE @Chunk INT=6;

SELECT t.ID
      ,A.MaxLen
      ,B.Nmbr AS ChunkNmbr
      ,SUBSTRING(t.LongString1,B.Nmbr*@Chunk+1,@Chunk) AS ChunkOfString1
      ,SUBSTRING(t.LongString2,B.Nmbr*@Chunk+1,@Chunk) AS ChunkOfString1
FROM @tbl t
CROSS APPLY(SELECT MAX(strLen) FROM (VALUES(LEN(t.LongString1)),(LEN(t.LongString2))) vals(strLen)) A(MaxLen)
CROSS APPLY(SELECT TOP(A.MaxLen/@Chunk + 1) 
                   ROW_NUMBER() OVER(ORDER BY (SELECT NULL))-1 
            FROM master..spt_values) B(Nmbr);

Новая идея: сначала мы используем APPLY, чтобы найти самую длинную строку в одном ряду. Мы должны выполнять вычисления чанка только для этого максимального числа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...