我有一个字符串:Brand=b1-b2&Vendor=v1-v2-v3&CustomField=cf1-cf2-cf3
我想做一张桌子..
**Name** | **Value**
------------- | ------
Brand | b1
Brand | b2
Vendor | v1
Vendor | v2
Vendor | v3
CustomField | cf1
CustomField | cf2
CustomField | cf3
感谢您的帮助
编辑注意:我试过,但我不认为这是性能
CREATE PROCEDURE [dbo].[SplitTableInStr]
(
@StrParameter NVARCHAR(MAX)
)
AS
BEGIN
DECLARE @Delimiter CHAR = '&',
@Index SMALLINT,
@Start SMALLINT,
@DelSize SMALLINT;
SET @DelSize = LEN(@Delimiter);
CREATE TABLE #FilteredItems
(
[Key] NVARCHAR(400),
[Values] NVARCHAR(MAX)
)
WHILE LEN(@StrParameter) > 0
BEGIN
SET @Index = CHARINDEX(@Delimiter, @StrParameter)
IF @Index = 0
BEGIN
DECLARE @Key NVARCHAR(400) = SUBSTRING(@StrParameter, 1, CHARINDEX('=', @StrParameter) - 1);
DECLARE @Values NVARCHAR(MAX) = SUBSTRING(@StrParameter, CHARINDEX('=', @StrParameter) + 1, LEN(@StrParameter));
INSERT INTO #FilteredItems ([Key],[Values])
VALUES (@Key,@Values)
BREAK
END
ELSE
BEGIN
DECLARE @IndexItem NVARCHAR(MAX) = SUBSTRING(@StrParameter, 1, @Index - 1);
DECLARE @IndexKey NVARCHAR(400) = SUBSTRING(@IndexItem, 1, CHARINDEX('=', @IndexItem) - 1);
DECLARE @IndexValues NVARCHAR(MAX) = SUBSTRING(@IndexItem, CHARINDEX('=', @IndexItem) + 1, LEN(@IndexItem));
INSERT INTO #FilteredItems ([Key],[Values])
VALUES (@IndexKey,@IndexValues)
SET @Start = @Index + @DelSize
SET @StrParameter = SUBSTRING(@StrParameter, @Start , LEN(@StrParameter) - @Start + 1)
END
END
DECLARE @KeyBase NVARCHAR(400),
@ValueBase NVARCHAR(MAX);
CREATE TABLE #DisplayOrderTmp
(
[EndName] NVARCHAR(400),
[EndValue] NVARCHAR(400)
)
WHILE EXISTS(SELECT * From #FilteredItems)
BEGIN
SELECT TOP 1 @KeyBase = [Key], @ValueBase = [Values] FROM #FilteredItems
DECLARE @OptionDelimiter CHAR = '-',
@OptionIndex SMALLINT,
@OptionStart SMALLINT,
@OptionDelSize SMALLINT;
SET @OptionDelSize = LEN(@OptionDelimiter)
WHILE LEN(@ValueBase) > 0
BEGIN
SET @OptionIndex = CHARINDEX(@OptionDelimiter, @ValueBase)
IF @OptionIndex = 0
BEGIN
INSERT INTO #DisplayOrderTmp VALUES (@KeyBase, @ValueBase)
BREAK;
END
ELSE
BEGIN
INSERT INTO #DisplayOrderTmp VALUES (@KeyBase, SUBSTRING(@ValueBase, 1, CHARINDEX(@OptionDelimiter, @ValueBase) - 1))
SET @OptionStart = @OptionIndex + @OptionDelSize
SET @ValueBase = SUBSTRING(@ValueBase, @OptionStart , LEN(@ValueBase) - @OptionStart + 1)
END
END
DELETE #FilteredItems WHERE [Key] = @KeyBase
END
SELECT * FROM #DisplayOrderTmp;
END
EXEC dbo.[SplitTableInStr] 'Brand=b1-b2&Vendor=v1-v2-v3&CustomField=cf1-cf2-cf3'
答案 0 :(得分:1)
使用带有cross apply()
declare @s nvarchar(4000) = 'Brand=b1-b2&Vendor=v1-v2-v3&CustomField=cf1-cf2-cf3';
select
Name = left(s.Item,charindex('=',s.Item)-1)
, Value = i.Item
from dbo.DelimitedSplitN4k(@s,'&') s
cross apply dbo.DelimitedSplitN4k(replace(s.Item,'=','-'),'-') i
where i.ItemNumber > 1
rextester演示:http://rextester.com/RTAT28301
返回:
+-------------+------+
| Name | Item |
+-------------+------+
| Brand | b1 |
| Brand | b2 |
| Vendor | v1 |
| Vendor | v2 |
| Vendor | v3 |
| CustomField | cf1 |
| CustomField | cf2 |
| CustomField | cf3 |
+-------------+------+
拆分字符串参考:
答案 1 :(得分:0)
我认为你应该用CLR功能(在C#中)获得最佳性能:
https://msdn.microsoft.com/en-us/library/ms131103.aspx
您可以手动拆分输入或使用命名组创建已编译的Regex来解析输入值。