【问题标题】:Split a string with multiple delimiters into 3 parts将具有多个分隔符的字符串拆分为 3 部分
【发布时间】:2017-04-29 18:22:23
【问题描述】:

我从 xml 文件中读取了一个字符串。我需要把它分成3部分。我需要在插入查询的选择语句中运行此查询。 更新 我想在插入语句的选择查询中使用它。

插入到 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.

我尝试了substringcharindex,但我只能得到第一个和第二个字符串,但我无法准确地得到位置字符串。任何帮助感谢 TIA。

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

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

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

【问题讨论】:

    标签: sql sql-server sql-server-2008 split


    【解决方案1】:

    这将按顺序为您提供字符串的三个部分

        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. '
      

      【讨论】:

      • 100% 同意你创造一次哲学(+1),但是,当我看到线性拆分函数时,它让我心碎。如果您想获得最佳性能,请查看此处的 udf stackoverflow.com/questions/40852241/…
      • 虽然clr 的表现最好。不过,您的功能仍然很棒。 https://sqlperformance.com/2012/07/t-sql-queries/split-strings@JohnCappelletti
      • @SqlZim 显然 CLR 会更快,但它并不总是一种选择。即一些托管环境和许多公司作为政策问题阻止 CLR。​​
      • 我同意,当您说顶级性能时,我只是在挑剔。所以我说你的功能还是很不错的! @JohnCappelletti
      • @SqlZim 我明白了:) 这只是为了让其他可能偶然发现这个讨论的人清楚。此外,我认为是您从我的圆形解决方案中删除了两个字节。我挖掘你的精确度。
      【解决方案3】:

      也试试这个。这会将字符串转换为动态字符串并给出值

      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
      

      【讨论】:

        【解决方案4】:

        您可以尝试使用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;
        

        这给了我以下结果

        【讨论】:

          【解决方案5】:
          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 |
          +-------+------------+--------------+
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-10
            • 1970-01-01
            • 1970-01-01
            • 2018-09-22
            • 1970-01-01
            • 2012-05-10
            相关资源
            最近更新 更多