SQL Server 2008中拆分单条记录Note列至多行的实现需求
SQL Server 2008 拆分长文本并更新插入记录
问题背景
现有Customer_Note表数据如下:
| Note_ID | Customer_ID | Note |
|---|---|---|
| 1 | 99 | This is a note I am adding to the record and its a very long record indeed |
| 2 | 102 | Note 2 |
需完成以下操作:
- 更新
Note_ID = 1的记录,将Note字段保留前20个字符; - 把该记录剩余的文本拆分为每行最多20字符的新记录插入表中,不影响其他记录。
最终期望结果:
| Note_ID | Customer_ID | Note |
|---|---|---|
| 1 | 99 | This is a note I am |
| 2 | 102 | Note 2 |
| 3 | 99 | adding to the record |
| 4 | 99 | and its a very lon |
| 5 | 99 | g record indeed |
解决方案
由于SQL Server 2008无内置字符串拆分函数,可通过变量存储+递归CTE实现需求,具体SQL代码如下:
-- 声明变量存储原记录信息与最大ID DECLARE @OriginalNote NVARCHAR(MAX), @CustomerID INT, @MaxNoteID INT; -- 获取目标记录的完整文本与客户ID SELECT @OriginalNote = Note, @CustomerID = Customer_ID FROM Customer_Note WHERE Note_ID = 1; -- 获取当前最大Note_ID,用于生成新记录的连续ID SELECT @MaxNoteID = MAX(Note_ID) FROM Customer_Note; -- 更新原记录,保留前20个字符 UPDATE Customer_Note SET Note = LEFT(@OriginalNote, 20) WHERE Note_ID = 1; -- 递归CTE拆分剩余文本并插入新记录 WITH SplitNotes AS ( -- 初始截取第21位开始的20个字符 SELECT 1 AS RowNum, SUBSTRING(@OriginalNote, 21, 20) AS NoteFragment, LEN(@OriginalNote) - 20 AS RemainingLength WHERE LEN(@OriginalNote) > 20 UNION ALL -- 递归截取后续片段 SELECT RowNum + 1, SUBSTRING(@OriginalNote, 21 + (RowNum * 20), 20), RemainingLength - 20 FROM SplitNotes WHERE RemainingLength > 20 ) INSERT INTO Customer_Note (Note_ID, Customer_ID, Note) SELECT @MaxNoteID + RowNum, @CustomerID, NoteFragment FROM SplitNotes WHERE NoteFragment <> ''; -- 过滤空片段
代码说明
- 变量存储:先获取目标记录的完整文本、客户ID,以及当前表中最大的
Note_ID,确保新插入记录的ID连续递增; - 更新原记录:使用
LEFT函数直接截取前20个字符更新原记录; - 递归拆分:通过递归CTE从第21位开始,每次截取20个字符,直到剩余文本长度为0,最后将所有有效片段插入表中。
注意事项
- 若原记录文本长度≤20,递归CTE不会生成数据,因此不会插入新记录;
- 若需处理超长文本(超过100段),需在CTE末尾添加
OPTION (MAXRECURSION 0)取消递归次数限制。
内容的提问来源于stack exchange,提问作者Nicola
相关产品推荐
相关产品推荐

