-2

我在存储过程中声明了一个临时表,其中我有四列地址,例如 AddressLine1、AddressLine2、AddressLine3、AddressLine4,每列的长度为 Varchar(50)

我想从现有表的临时表中插入数据,以便现有表将地址存储在 AddressLine1 内,所以我想将 AddressLine1 中的地址从现有表插入到临时表,但是如果地址超过 50 的长度并带有空格,那么我想插入剩余的地址到 AddressLine2 等等

所以总而言之,我想根据列的长度(即 50)划分地址,然后将其存储在临时表中的 addressLine1、addressLine2、addressLine3、addressLine4 之间

select DATALENGTH(ADDRESSLINE1)
from PASSENGER
where DATALENGTH(ADDRESSLINE1) > 50
4

1 回答 1

2

您可以通过一些递归 cte 和子字符串来实现这一点......遵循一个可以肯定被优化/缩短但应该明确这一点的快速示例:

DECLARE @x NVARCHAR(200) = N'This is some test and this still is the test and yet here the test continues and so on until the test is finished';

WITH cte1 AS(
-- evaluate all positions of spaces
SELECT @x as txt, CHARINDEX(' ', @x) as idx
UNION ALL
SELECT txt, CHARINDEX(' ', txt, idx+1) as idx
  FROM cte1
  WHERE CHARINDEX(' ', txt, idx+1) >0
),
cte2 AS(
-- evaluate groups basing of the length of 50 as desired output length
SELECT *, idx/50 - CASE WHEN idx%50 = 0 THEN 1 ELSE 0 END AS dividx
  FROM cte1
),
cte3 AS(
-- evaluate max space position per group
SELECT txt, dividx, max(idx) maxIdx
  FROM cte2
  GROUP BY txt, dividx
),
cte4 AS(
-- evaluate required start and end position for substring operation
SELECT txt, dividx
      ,ISNULL(LAG(maxIdx) OVER (PARTITION BY txt ORDER BY dividx)+1, 1) AS minIdx
      ,CASE WHEN LEAD(maxIdx) OVER (PARTITION BY txt ORDER BY dividx) IS NULL THEN len(txt) ELSE maxIdx END AS maxIdx
  FROM cte3
)
-- perform substring
SELECT SUBSTRING(txt, minIdx, maxIdx-minIdx+1) AS txt
  FROM cte4
  OPTION (MAXRECURSION 0)
于 2021-04-07T09:52:16.950 回答