在 T-SQL 中将长字符串查询结果拆分为多行

N S*_*son 1 sql t-sql sql-server stored-procedures view

我在 MS SQL Server 中有一个表,其中包含多个文本字段,这些字段可以包含很长的字符串(从 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   
Run Code Online (Sandbox Code Playgroud)

Shn*_*ugo 5

你可以尝试这样做:

模拟您的问题的模型

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');
Run Code Online (Sandbox Code Playgroud)

--我们可以指定块的长度

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);
Run Code Online (Sandbox Code Playgroud)

简而言之:

我们使用一个带有APPLY计算TOP子句的技巧。源master..spt_values只是一个包含很多行的公用表。我们不需要这些值,只需要一组来使用 计算运行数字ROW_NUMBER()APPLY将被称为row-by-row。这意味着长字符串会比短字符串创建更多的数字。

为了获得你的块,我使用了一个简单的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);
Run Code Online (Sandbox Code Playgroud)

新想法:我们使用第APPLY一个来查找一行中最长的字符串。我们必须仅针对这个最大数量进行块计算。