在SQL Server 2008或2012中拆分字符串

时间:2015-01-10 20:32:07

标签: sql-server

我有一个名为HR的表,名为Details的列,其格式如下,如下所示

Name=Jhon|Age=36|Job=Sales Manager|Job Location=Texas|Add_Date:09/24/2009

Name=Tom|Age=27|Job=Sales Man|Job Location=Texas|Add_Date:07/19/2014

Name=Ferdinan|Age=38|Job=Sales Man|Job Location=Texas|Add_Date:12/24/2014

Name=Jhonson|Age=29|Job=Marketing Manager|Job Location=Texas|Add_Date:12/26/2014

Name=Mikel|Age=26|Job=Technician|Job Location=Texas|Add_Date:12/27/2014

Name=Steve|Age=25|Job=Technician|Job Location=Los Angeles|Add_Date:12/27/2014

Name=Rob|Age=29|Job=Programmer|Job Location=NC|Add_Date:12/28/2014

表会每天更新记录,我需要提取这些记录并插入到新表中,其中存在基于日期添加的所有提到的字段,表示无需更新旧记录

表名为HR_2015Records。字段名称为NameAgeJobJob location

请帮助我实现这个目标

2 个答案:

答案 0 :(得分:1)

我今天早些时候回答了“同样”的问题。 SQL Server 2008 R2 - How to split my varchar column string and get 3rd index string

这是一个将内联分割字符串的函数....

CREATE FUNCTION [dbo].[FN_SPLIT] ( --SELECT DBO.FN_SPLIT('TEST1 , TEST2', 2, ',')
    @s varchar(512),
    @i int,
    @sep char(1) = ',')
RETURNS varchar(512)
AS
BEGIN
    DECLARE @Ret    VARCHAR(512);

    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT @Ret =
    RTRIM(SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END))
    FROM Pieces
    WHERE pn = @i

    RETURN @Ret;
END

这是一个表值函数,它将返回一个值表

CREATE FUNCTION [dbo].[FN_SPLIT_TBL](@InExp varchar(8000), @Sep varchar(10)) --SELECT * FROM DBO.[FN_SPLIT_TBL]('TEST1,TEST2', ',')
RETURNS @Res    TABLE(
    Pos         int,
    Value       varchar(max))
AS
BEGIN
    WITH Pieces(pn, start, stop) AS (
        SELECT 1, 1, CHARINDEX(@Sep, @InExp)
        UNION ALL
        SELECT pn + 1, stop + 1, CHARINDEX(@sep, @InExp, stop + 1)
        FROM Pieces
        WHERE stop > 0
    )

    INSERT INTO @Res
    SELECT pn, SUBSTRING(@InExp, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
    FROM Pieces OPTION (MAXRECURSION 0);

    RETURN;
END

使用第一个函数,您可以按照您想要的格式返回数据......

SELECT 
dbo.[FN_SPLIT](data.Name, 2, '=') as Name,
dbo.[FN_SPLIT](data.Age, 2, '=') as Age,
dbo.[FN_SPLIT](data.Job, 2, '=') as Job,
dbo.[FN_SPLIT](data.Location, 2, '=') as Location,
dbo.[FN_SPLIT](data.Add_Date, 2, '=') as Add_Date
FROM (
    SELECT 
    dbo.[FN_SPLIT](Details, 1, '|') as Name,
    dbo.[FN_SPLIT](Details, 2, '|') as Age,
    dbo.[FN_SPLIT](Details, 3, '|') as Job,
    dbo.[FN_SPLIT](Details, 4, '|') as Location,
    dbo.[FN_SPLIT](Details, 5, '|') as Add_Date
    FROM HR) data

或者使用两种功能的组合,您可以像这样返回数据。

SELECT dbo.[FN_SPLIT](Name.Value, 2, '=') as Name,
dbo.[FN_SPLIT](Age.Value, 2, '=') as Age,
dbo.[FN_SPLIT](Job.Value, 2, '=') as Job,
dbo.[FN_SPLIT](Location.Value, 2, '=') as Location,
dbo.[FN_SPLIT](Add_Date.Value, 2, '=') as Add_Date
FROM HR data
    CROSS APPLY FN_SPLIT_TBL(data.Details, '|') Name
    CROSS APPLY FN_SPLIT_TBL(data.Details, '|') Age
    CROSS APPLY FN_SPLIT_TBL(data.Details, '|') Job
    CROSS APPLY FN_SPLIT_TBL(data.Details, '|') Location
    CROSS APPLY FN_SPLIT_TBL(data.Details, '|') Add_Date
WHERE Name.Pos = 1 AND Age.Pos = 2 AND Job.Pos = 3 AND Location.Pos = 4 AND Add_Date.Pos = 5

我不能说哪个更快,你需要检查你的环境。我可以说表现不会很好。

希望有所帮助

答案 1 :(得分:0)

简单的方法是使用Choose, Substring, Replace and Charindex字符串函数。试试这个。

DECLARE @str VARCHAR(1000)='Name=Jhon|Age=36|Job=Sales Manager|Job Location=Texas|Add_Date:09/24/2009',
        @sql NVARCHAR(max)

SET @str = ''''+ Replace(Replace(@str, '|', ''','''), ':', '=')+ ''''

SET @sql= 'select substring(choose(1,'+@str+'),charindex(''='',choose(1,'+@str+'))+1,len(choose(1,'+@str+'))) as Name,
                  substring(choose(2,'+@str+'),charindex(''='',choose(2,'+@str+'))+1,len(choose(2,'+@str+'))) as Age,
                  substring(choose(3,'+@str+'),charindex(''='',choose(3,'+@str+'))+1,len(choose(3,'+@str+'))) as Job,
                  substring(choose(4,'+@str+'),charindex(''='',choose(4,'+@str+'))+1,len(choose(4,'+@str+'))) as [Job Location],
                  substring(choose(5,'+@str+'),charindex(''='',choose(5,'+@str+'))+1,len(choose(5,'+@str+'))) as [Add_Date]'

--print @sql
EXEC Sp_executesql @sql 

<强> 结果

Name    Age Job             Job Location  Add_Date
----    --- -------------   ------------  ----------
Jhon    36  Sales Manager   Texas         09/24/2009