将具有多个分隔符的字符串拆分为3个部分。

3

我从一个XML文件中读取了一个字符串。我需要将它分成三个部分。我需要在选择语句中运行此查询以进行插入查询。 更新 我应该在选择查询中使用它来进行插入语句。

插入到table1(col1,col2,company,station,location,coln) 选择(这里我想为每个列使用此查询。)

字符串示例:

@declare exValue1 nvarchar(100) = 'Tempo > XNX (Marc) > Stores/Parts';
@declare exValue2 nvarchar(100) = 'Sedan 12 > XNX (Peter Inc) > Stores/Inventory'; 
@declare @company varchar(25);
@declare @station varchar(25);
@declare @location varchar(50);

分隔符是4个字符,始终相同。

例如第一个字符串,我需要拆分并分配。

 Tempo to company, XNX (Marc) to station, Stores/Parts to location.

例如第二个字符串。
Sedan 12 to company, XNX (Peter Inc) to station, Stores/Inventory to location.

我尝试使用 charindex 剪辑字符串,但我只能获取第一和第二个字符串,无法准确获取定位字符串。任何帮助将不胜感激。谢谢。

select @company = SUBSTRING(@exValue1, 1, CHARINDEX('>', @test) - 1)

select @station = SUBSTRING (@exValue1, CHARINDEX('>', @test) + 4, LEN(@test))

我无法正确确定位置和站点。

5个回答

4
这将按顺序为您提供字符串的三个部分。
    declare @exValue1 nvarchar(100) = 'Tempo > XNX (Marc) > Stores/Parts';

    SELECT LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS slices
    FROM (SELECT CAST('<XMLRoot><RowData>' + REPLACE(@exValue1,'&gt;','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x)t
    CROSS APPLY x.nodes('/XMLRoot/RowData')m(n)

但如果你想使用变量,这里有一个例子。
declare @exValue1 nvarchar(100) = 'Tempo &gt; XNX (Marc) &gt; Stores/Parts';

select  SUBSTRING(@exValue1, 1, CHARINDEX('&gt;', @exValue1) - 1)
set @exValue1 = SUBSTRING(@exValue1,CHARINDEX('&gt;', @exValue1)+4,len(@exValue1))
select  SUBSTRING(@exValue1, 1, CHARINDEX('&gt;', @exValue1) - 1)
set @exValue1 = SUBSTRING(@exValue1,CHARINDEX('&gt;', @exValue1)+4,len(@exValue1))
select  @exValue1

2
创建函数一次,可重复使用百万次 :)
CREATE  FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX) )
RETURNS
 @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

 DECLARE @name NVARCHAR(255)
 DECLARE @pos INT

 WHILE CHARINDEX('&gt;', @stringToSplit) > 0
 BEGIN
  SELECT @pos  = CHARINDEX('&gt;', @stringToSplit)  
  SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

  INSERT INTO @returnList 
  SELECT @name

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+4, LEN(@stringToSplit)-@pos)
 END

 INSERT INTO @returnList
 SELECT @stringToSplit

 RETURN
END

使用该函数的方法如下:

declare @exValue1 nvarchar(100) = 'Tempo &gt; XNX (Marc) &gt; Stores/Parts';

declare @company varchar(25)
set @company=(select top 1 name from dbo.splitstring(@exValue1))
declare @station varchar(25)
set @station=(select top 1 name from dbo.splitstring(@exValue1) where name not in (select top 1 name from dbo.splitstring(@exValue1)))
declare @location varchar(50)
set @location=(select top 1 name from dbo.splitstring(@exValue1) where name not in (select top 2 name from dbo.splitstring(@exValue1)))



print @company+' to comapny, '+@station+' to station, '+@location+' to location. '

我完全同意你的“一次创建”哲学(+1),但是当我看到线性分割函数时,我的心都碎了。如果你想要最佳性能,请参考这里的UDF:http://stackoverflow.com/questions/40852241/how-to-create-a-view-showing-rows-from-splitted-data/40852549#40852549 - John Cappelletti
最佳性能应该使用 clr。不过,您的函数仍然非常出色。https://sqlperformance.com/2012/07/t-sql-queries/split-strings @JohnCappelletti - SqlZim
@SqlZim 显然,CLR会更快,但并非总是可行的选择。例如,在某些托管环境中和许多公司将CLR作为一项政策进行阻止。 - John Cappelletti
我同意,当你说“最佳性能”时,我只是有点挑剔。这就是为什么我说你的函数仍然非常棒!@JohnCappelletti - SqlZim
@SqlZim 我明白了 :) 这只是为了让其他可能会遇到这个讨论的人更清楚。此外,我认为是你将我的圆解决方案减少了两个字节。我喜欢你的精度。 - John Cappelletti

2

也可以尝试这个方法。它会将字符串转换为动态类型并返回相应的值。

declare @exValue1 nvarchar(100) = 'Tempo &gt; XNX (Marc) &gt; Stores/Parts';
declare @exValue2 nvarchar(100) = 'Sedan 12 &gt; XNX (Peter Inc) &gt; Stores/Inventory'; 
declare @company varchar(25);
declare @station varchar(25);
declare @location varchar(50);
DECLARE @Tbl AS TABLE(company varchar(25), station varchar(25), location varchar(50))

SET @exValue1 = 'SELECT '''+REPLACE(@exValue1,'&gt;',''' , ''')+''''
INSERT INTO @Tbl
EXEC(@exValue1)
SET @exValue2 = 'SELECT '''+REPLACE(@exValue2,'&gt;',''' , ''')+''''
INSERT INTO @Tbl
EXEC(@exValue2)

SELECT * FROM @Tbl

0
你可以尝试使用REVERSE()来获取Location,如下所示。
declare @exValue1 nvarchar(100) = 'Tempo &gt; XNX (Marc) &gt; Stores/Parts';
declare @exValue2 nvarchar(100) = 'Sedan 12 &gt; XNX (Peter Inc) &gt; Stores/Inventory'; 
declare @company varchar(25);
declare @station varchar(25);
declare @location varchar(50);

select @company= SUBSTRING(@exValue1,1,CHARINDEX('&gt;',@exValue1)-1)
select @location = reverse(SUBSTRING(reverse(@exValue1),1, CHARINDEX(';tg&',reverse(@exValue1))-1))
select @station = REPLACE(REPLACE(REPLACE(@exValue1,@company,''),@location,''),'&gt;','')

select @company company, @station station, @location location;

这给了我以下结果

enter image description here


0
declare @exValue1 nvarchar(100) = 'Tempo &gt; XNX (Marc) &gt; Stores/Parts'
       ,@company  varchar(25)
       ,@station  varchar(25)
       ,@location varchar(50)

select  @company  = x.value('(/r/e)[1]','nvarchar(25)') 
       ,@station  = x.value('(/r/e)[2]','nvarchar(25)') 
       ,@location = x.value('(/r/e)[3]','nvarchar(50)') 

from   (select cast ('<r><e>'+replace(@exValue1,'&gt;','</e><e>')+'</e></r>' as xml) as x) x


select  @company,@station,@location

+-------+------------+--------------+
| Tempo | XNX (Marc) | Stores/Parts |
+-------+------------+--------------+

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接