将含多值多行的大分隔字符串插入SQL Server表的实现方案
解决分隔字符串拆分插入数据库表的存储过程方案
针对你提供的这种分号分隔行、逗号分隔列的字符串(示例:"1,1a,1b;2,2a,2b;3,3a,3b"),我给你整理了两种适合SQL Server的存储过程实现方案,能高效处理数百条数据的插入需求,目标表结构如下:
| Col1 | Col2 | Col3 |
|---|---|---|
| 1 | 1a | 1b |
| 2 | 2a | 2b |
| 3 | 3a | 3b |
方案一:使用SQL Server 2016+内置函数STRING_SPLIT
如果你的SQL Server版本是2016及以上,直接用内置的STRING_SPLIT函数会非常简洁,性能也不错:
CREATE PROCEDURE dbo.SplitAndInsertData @InputString NVARCHAR(MAX) AS BEGIN SET NOCOUNT ON; -- 先按分号拆分得到每一行的字符串,再按逗号拆分每一行的列 INSERT INTO YourTableName (Col1, Col2, Col3) SELECT -- 提取第一列(逗号前的内容) PARSENAME(REPLACE(value, ',', '.'), 3) AS Col1, -- 提取第二列 PARSENAME(REPLACE(value, ',', '.'), 2) AS Col2, -- 提取第三列 PARSENAME(REPLACE(value, ',', '.'), 1) AS Col3 FROM STRING_SPLIT(@InputString, ';') WHERE -- 过滤空行(比如字符串末尾可能有多余分号) RTRIM(LTRIM(value)) <> '' -- 确保每一行都是3列,避免插入错误 AND LEN(value) - LEN(REPLACE(value, ',', '')) = 2; PRINT '数据插入完成,共插入' + CAST(@@ROWCOUNT AS VARCHAR) + '条记录'; END GO
说明:
STRING_SPLIT(@InputString, ';')把输入字符串按分号拆分成多行,每行是一个类似"1,1a,1b"的子串;REPLACE(value, ',', '.')把逗号换成点,因为PARSENAME函数默认按点分隔提取片段,刚好适配3列的提取需求;- 最后的WHERE条件过滤空行,同时校验每行恰好有2个逗号(对应3列),避免插入不符合结构的数据。
方案二:兼容低版本SQL Server的自定义拆分函数
如果你的SQL Server版本低于2016,没有STRING_SPLIT,可以先创建一个自定义的字符串拆分函数,再编写存储过程:
第一步:创建自定义拆分函数
CREATE FUNCTION dbo.SplitString ( @InputString NVARCHAR(MAX), @Delimiter NVARCHAR(5) ) RETURNS @Result TABLE (Value NVARCHAR(MAX)) AS BEGIN DECLARE @StartIndex INT, @EndIndex INT SET @StartIndex = 1 -- 确保字符串末尾有分隔符,避免最后一行被忽略 IF SUBSTRING(@InputString, LEN(@InputString) - LEN(@Delimiter) + 1, LEN(@Delimiter)) <> @Delimiter BEGIN SET @InputString = @InputString + @Delimiter END WHILE CHARINDEX(@Delimiter, @InputString) > 0 BEGIN SET @EndIndex = CHARINDEX(@Delimiter, @InputString) INSERT INTO @Result(Value) SELECT SUBSTRING(@InputString, @StartIndex, @EndIndex - @StartIndex) SET @InputString = SUBSTRING(@InputString, @EndIndex + LEN(@Delimiter), LEN(@InputString)) END RETURN END GO
第二步:编写存储过程
CREATE PROCEDURE dbo.SplitAndInsertData_Legacy @InputString NVARCHAR(MAX) AS BEGIN SET NOCOUNT ON; INSERT INTO YourTableName (Col1, Col2, Col3) SELECT PARSENAME(REPLACE(RowValue.Value, ',', '.'), 3) AS Col1, PARSENAME(REPLACE(RowValue.Value, ',', '.'), 2) AS Col2, PARSENAME(REPLACE(RowValue.Value, ',', '.'), 1) AS Col3 FROM dbo.SplitString(@InputString, ';') AS RowValue WHERE RTRIM(LTRIM(RowValue.Value)) <> '' AND LEN(RowValue.Value) - LEN(REPLACE(RowValue.Value, ',', '')) = 2; PRINT '数据插入完成,共插入' + CAST(@@ROWCOUNT AS VARCHAR) + '条记录'; END GO
使用方法
不管用哪个方案,调用存储过程都很简单:
EXEC dbo.SplitAndInsertData '1,1a,1b;2,2a,2b;3,3a,3b';
额外提示
- 记得把
YourTableName替换成你实际的表名; - 如果字符串内容包含点(
.),PARSENAME方法会失效,这时候可以换成用CHARINDEX逐列提取,示例代码如下:SELECT SUBSTRING(value, 1, CHARINDEX(',', value) - 1) AS Col1, SUBSTRING(value, CHARINDEX(',', value) + 1, CHARINDEX(',', value, CHARINDEX(',', value) + 1) - CHARINDEX(',', value) - 1) AS Col2, SUBSTRING(value, CHARINDEX(',', value, CHARINDEX(',', value) + 1) + 1, LEN(value)) AS Col3 - 对于几百条数据的量级,这两种方案的性能都完全够用,不需要担心效率问题。
内容的提问来源于stack exchange,提问作者user255377
相关产品推荐
相关产品推荐

