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

Sql server 在SQL Server 2008或2012中拆分字符串,sql-server,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/

我有一个名为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
。字段名称为
名称
年龄
作业
作业位置

请帮助我实现这一目标

我今天早些时候回答了“相同”的问题

下面是一个函数,它将内联拆分字符串

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
我不能说哪一个会更快,你需要检查你的环境。我可以说表演不会很好


希望有帮助的简单的方法是使用
选择、子字符串、替换和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 
结果


是否有可能改变插入此数据的过程,以便在将不同片段连接到该垃圾中之前将其插入到
HR_2015;记录中
Name    Age Job             Job Location  Add_Date
----    --- -------------   ------------  ----------
Jhon    36  Sales Manager   Texas         09/24/2009