我正在将以下参数传递给我的存储过程 -
@AddOns = 23:2,33:1,13:5
我需要用逗号分割字符串 -
SET @Addons = @Addons + ','
set @pos = 0
set @len - 0
While CHARINDEX(',', @Addons, @pos+1)>0
Begin
SET @len = CHARINDEX(','), @Addons, @pos+1) - @pos
SET @value = SUBSTRING(@Addons, @pos, @len)
所以现在@value = 23:2我需要得到23这是我的ID和2这是我的数量。这是我的其余代码 -
INSERT INTO TABLE(ID, Qty)
VALUES(@ID, @QTY)
set @pos = CHARINDEX(',', @Addons, @pos+@len) + 1
END
那么在INSERT
语句中,在单独的字段中获取23和2的值的最佳方法是什么?
首先,你将键值对的集合分成行(看起来你已经到了那么远),然后你得到冒号的位置并使用它来做两个SUBSTRING
操作来分开键和值。
此外,这可以比将每行的键和值存储到单独的变量中更有效,只是为了插入表中。如果你从INSERT
中SELECT
将这些数据分开,它将是一个基于集合的操作而不是逐行。
例如:
DECLARE @AddOns VARCHAR(1000) = N'23:2,33:1,13:5,999:45';
;WITH pairs AS
(
SELECT [SplitVal] AS [Value], CHARINDEX(N':', [SplitVal]) AS [ColonIndex]
FROM SQL#.String_Split(@AddOns, N',', 1) -- https://SQLsharp.com/
)
SELECT *,
SUBSTRING(pairs.[Value], 1, pairs.[ColonIndex] - 1) AS [ID],
SUBSTRING(pairs.[Value], pairs.[ColonIndex] + 1, 1000) AS [QTY]
FROM pairs;
/*
Value ColonIndex ID QTY
23:2 3 23 2
33:1 3 33 1
13:5 3 13 5
999:45 4 999 45
*/
GO
对于该示例,我使用的是SQL#库(我是其作者)中的SQLCLR字符串拆分器,可在免费版中找到。您可以使用任何您喜欢的分割器,包括SQL Server 2016中引入的内置STRING_SPLIT
。
它将使用如下:
DECLARE @AddOns VARCHAR(1000) = N'23:2,33:1,13:5,999:45';
;WITH pairs AS
(
SELECT [value] AS [Value], CHARINDEX(N':', [value]) AS [ColonIndex]
FROM STRING_SPLIT(@AddOns, N',') -- built-in function starting in SQL Server 2016
)
INSERT INTO dbo.TableName (ID, QTY)
SELECT SUBSTRING(pairs.[Value], 1, pairs.[ColonIndex] - 1) AS [ID],
SUBSTRING(pairs.[Value], pairs.[ColonIndex] + 1, 1000) AS [QTY]
FROM pairs;
当然,SQL#的Full(即付费)版本包括一个额外的分配器,用于处理键值对。它叫做String_SplitKeyValuePairs,工作原理如下:
DECLARE @AddOns VARCHAR(1000) = N'23:2,33:1,13:5,999:45';
SELECT *
FROM SQL#.String_SplitKeyValuePairs(@AddOns, N',', N':', 1, NULL, NULL, NULL);
/*
KeyID Key Value
1 23 2
2 33 1
3 13 5
4 999 45
*/
GO
因此,它将使用如下:
DECLARE @AddOns VARCHAR(1000) = N'23:2,33:1,13:5,999:45';
INSERT INTO dbo.[TableName] ([Key], [Value])
SELECT kvp.[Key], kvp.[Value]
FROM SQL#.String_SplitKeyValuePairs(@AddOns, N',', N':', 1, NULL, NULL, NULL) kvp;
我将在@ gofr1对这个问题给出的答案的启发下再次尝试这个...
How to insert bulk of column data to temp table?
该答案显示了如何使用XML变量和nodes method来分割逗号分隔数据并将其插入表中的各个列。在我看来,这与你在这里尝试的非常相似。
看看这个SQL。它当然不具备简洁性,只是具有“分裂”功能,但它似乎比根据冒号的位置切断字符串更好。
诺埃尔