11

我有一个这样的字符串:

72594206916,2,1/2/08,Tacoma,WA:72594221856,5,5/7/13,San Francisco,CA:72594221871,99,12/30/12,Dallas,TX

这基本上是 3 行中的每行 5 个值(来自 ASP.NET 网格)。我需要在 SQL Server 表中将此字符串拆分为 5 列和 3 行。单个值用逗号分隔,行用冒号分隔。

我找到了一个将字符串拆分成片段的函数,我可以从这个字符串中取出行:

declare @testString varchar(100)
set @testString = '72594206916,2,1/2/08,Tacoma,WA:72594221856,5,5/7/13,San Francisco,CA:72594221871,99,12/30/12,Dallas,TX'

select *
from dbo.SplitString(@testString, ':')

给我:

72594206916,2,1/2/08,Tacoma,WA
72594221856,5,5/7/13,San Francisco,CA
72594221871,99,12/30/12,Dallas,TX

这给了我一个包含三行的结果集(函数输出一个表)。我可以同时再次调用此函数并以某种方式将其输出插入表中吗?

4

8 回答 8

13

假设您的拆分返回列名项目

insert <table> (colname)
select y.item
from dbo.SplitString(@testString, ':') x
cross apply
dbo.SplitString(x.item, ',') y
于 2013-11-10T04:11:41.173 回答
4

Romil 的函数定义
在您的 Sql Server 中创建此函数

CREATE FUNCTION Split (
      @InputString                  VARCHAR(8000),
      @Delimiter                    VARCHAR(50)
)

RETURNS @Items TABLE (
      Item                          VARCHAR(8000)
)

AS
BEGIN
      IF @Delimiter = ' '
      BEGIN
            SET @Delimiter = ','
            SET @InputString = REPLACE(@InputString, ' ', @Delimiter)
      END

      IF (@Delimiter IS NULL OR @Delimiter = '')
            SET @Delimiter = ','

--INSERT INTO @Items VALUES (@Delimiter) -- Diagnostic
--INSERT INTO @Items VALUES (@InputString) -- Diagnostic

      DECLARE @Item                 VARCHAR(8000)
      DECLARE @ItemList       VARCHAR(8000)
      DECLARE @DelimIndex     INT

      SET @ItemList = @InputString
      SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
      WHILE (@DelimIndex != 0)
      BEGIN
            SET @Item = SUBSTRING(@ItemList, 0, @DelimIndex)
            INSERT INTO @Items VALUES (@Item)

            -- Set @ItemList = @ItemList minus one less item
            SET @ItemList = SUBSTRING(@ItemList, @DelimIndex+1, LEN(@ItemList)-@DelimIndex)
            SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
      END -- End WHILE

      IF @Item IS NOT NULL -- At least one delimiter was encountered in @InputString
      BEGIN
            SET @Item = @ItemList
            INSERT INTO @Items VALUES (@Item)
      END

      -- No delimiters were encountered in @InputString, so just return @InputString
      ELSE INSERT INTO @Items VALUES (@InputString)

      RETURN

END -- End Function
GO

传递你的参数
因为它是一个表函数,你将 SELECT * FROM this_Function 就像你对表做的那样

declare @testString varchar(100)
set @testString = '72594206916,2,1/2/08,Tacoma,WA:72594221856,5,5/7/13,San Francisco,CA:72594221871,99,12/30/12,Dallas,TX'

SELECT * FROM Split(@testString, ',')

结果集

Item
72594206916
2
1/2/08
Tacoma
WA:72594221856
5
5/7/13
San Francisco
CA:72594221871
99
12/30/12
Dallas

您现有的代码

select *
from dbo.SplitString(@testString, ':')

第二个参数需要是分隔符,因为您将:作为第二个参数传递,所以它会破坏您:在传递字符串中找到的字符串,这显然在 2 个位置,并且您在结果集中返回 3 个值/字符串

                          String1/Value1                             String2/Value2                    String3/Value3
set @testString = '72594206916,2,1/2/08,Tacoma,WA  :   72594221856,5,5/7/13,San Francisco,CA  :  72594221871,99,12/30/12,Dallas,TX'
于 2013-11-10T01:36:30.660 回答
4

创建这个 SQL 函数:

CREATE FUNCTION [dbo].[StringSplit](@input NVARCHAR(MAX), @delimiter CHAR(1)=',') 
       RETURNS @returnTable TABLE(item NVARCHAR(100)) AS  
     BEGIN 
        IF @input IS NULL RETURN;
        DECLARE @currentStartIndex INT, @currentEndIndex INT,@length INT;
        SET @length=LEN(@input);
        SET @currentStartIndex=1;

        SET @currentEndIndex=CHARINDEX(@delimiter,@input,@currentStartIndex);
        WHILE (@currentEndIndex<>0)
          BEGIN
            INSERT INTO @returnTable VALUES (LTRIM(SUBSTRING(@input, @currentStartIndex, @currentEndIndex-@currentStartIndex)))
            SET @currentStartIndex=@currentEndIndex+1;
            SET @currentEndIndex=CHARINDEX(@delimiter,@input,@currentStartIndex);
          END

        IF (@currentStartIndex <= @length)
          INSERT INTO @returnTable 
            VALUES (LTRIM(SUBSTRING(@input, @currentStartIndex, @length-@currentStartIndex+1)));
        RETURN;
     END;

使用示例:

DECLARE @testString VARCHAR(100)
SET @testString = '72594206916,2,1/2/08,Tacoma,WA:72594221856,5,5/7/13,San Francisco,CA:72594221871,99,12/30/12,Dallas,TX'

SELECT *
FROM [dbo].[StringSplit](@testString, DEFAULT)

结果(表):

72594206916
2
1/2/08
Tacoma
WA:72594221856
5
5/7/13
San Francisco
CA:72594221871
99
12/30/12
Dallas
于 2016-06-08T11:15:09.703 回答
2

类似于 M.Ali 上面给出的内容,但更短:

Use [Database_Name]
Go;

 CREATE FUNCTION Split
(
@RowData nvarchar(MAX),
@SplitOn nvarchar(MAX)
)  
RETURNS @RtnValue table 
(
Data nvarchar(MAX)
) 
AS  
BEGIN 
Declare @Cnt int
Set @Cnt = 1

While (Charindex(@SplitOn,@RowData)>0)
Begin
    Insert Into @RtnValue (data)
    Select 
        Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1)))

    Set @RowData = Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData))
    Set @Cnt = @Cnt + 1
End

Insert Into @RtnValue (data)
Select Data = ltrim(rtrim(@RowData))

Return
END

然后从函数中选择,如上例所示:

USE [Database_Name]
GO
declare @testString varchar(100)
set @testString = '72594206916,2,1/2/08,Tacoma,WA:72594221856,5,5/7/13,San   Francisco,CA:72594221871,99,12/30/12,Dallas,TX'

SELECT * FROM Split(@testString, ',')
于 2014-04-08T17:46:51.540 回答
1
declare @fqdn_list varchar(max) = 'test1.qa.local,test2.qa.local,test3.qa.local'
-- temp table
DECLARE @fqdn_tbl TABLE (   fqdn nvarchar(50) )

INSERT INTO @fqdn_tbl  SELECT LTRIM(RTRIM(split.a.value('.', 'NVARCHAR(MAX)'))) AS fqdn   FROM (
    SELECT CAST ('<M>' + REPLACE(@fqdn_list, ',', '</M><M>') + '</M>' AS XML) AS data   ) AS a   CROSS APPLY data.nodes ('/M') AS split(a)

select * from  @fqdn_tbl
于 2017-10-11T18:29:39.390 回答
1

如果您的数据库兼容 130 或更高版本,您可以使用内置函数 STRING_SPLIT:

https://database.guide/how-to-convert-a-comma-separated-list-into-rows-in-sql-server/

于 2020-02-28T17:46:20.893 回答
0

试试这个代码:

SELECT value
FROM STRING_SPLIT(@testString, ',')
于 2020-10-03T12:26:40.307 回答
-1

你忘了最后一行。在您的示例中,未考虑“TX”。你应该检查剩余的文本 avec While 循环

于 2016-09-06T12:29:40.967 回答