使用 SQL Server 将字符串数据块解析为表格数据集

Posted

技术标签:

【中文标题】使用 SQL Server 将字符串数据块解析为表格数据集【英文标题】:Parse Chunk of String Data into Tabular Data set using SQL Server 【发布时间】:2021-09-02 14:50:03 【问题描述】:

我从 .NET Web 应用程序的用户界面中获取大量字符串数据。 .NET 开发人员想要调用一个用户定义的存储过程,该存储过程需要将字符串数据解析为表格格式。

示例String数据如下:

[EMPDetailsEntity(id=1, FName=ABC, Active=YES, LName=CCC, Created=Mon Jun 07 20:00:00 EDT 2021, UpdatedBy = null)
,EMPDetailsEntity(id=2, FName=DEF, Active=YES, LName=F'FF, Created=Sun Jun 13 20:00:00 EDT 2021, UpdatedBy = null)
,EMPDetailsEntity(id=3, FName=GH,I, Active=YES, LName=III, Created=Wed Jun 16 20:20:20 EDT 2021, UpdatedBy = null)
,EMPDetailsEntity(id=4, FName=JKL, Active=YES, LName=LL',L, Created=Wed Jun 16 20:20:20 EDT 2021, UpdatedBy = null)]

我想将上述字符串数据生成表格格式。如下所示:

ID  FirstName  LastName  Active  CreatedDT   UpdatedBy
1     ABC        CCC       YES     06/07/2021  Null
2     DEF        FFF       YES     06/13/2021  Null
3     GHI        III       YES     06/16/2021  Null
4     JKL        LLL       YES     06/16/2021  Null

请任何人帮助我如何将字符串数据解析为表格格式,以便我可以直接将数据推送到 SQL 表中。

【问题讨论】:

告诉 UI 开发人员以 XML(任何版本)或 JSON(SQL 2016+)格式向您发送数据。 我们能否确认任何值中都没有逗号?如果是这样,我们可以将其解析为逗号分隔的值。 字符串中传递的任何值将来都可以有逗号。 如果可以有逗号,您最好在测试数据中包含一个示例。 有趣的是,LName=LL',L 作为输入变成了LLL 作为输出。与FName=GH,IGHI 类似。适用什么规则?不能写规则就不能写代码。 【参考方案1】:

借助与条件聚合相结合的表值函数

示例或dbFiddle

Declare @S varchar(max) = '
[EMPDetailsEntity(id=1, FName=ABC, Active=YES, LName=CCC, Created=Mon Jun 07 20:00:00 EDT 2021, UpdatedBy = null)
,EMPDetailsEntity(id=2, FName=DEF, Active=YES, LName=F''FF, Created=Sun Jun 13 20:00:00 EDT 2021, UpdatedBy = null)
,EMPDetailsEntity(id=3, FName=GH,I, Active=YES, LName=III, Created=Wed Jun 16 20:20:20 EDT 2021, UpdatedBy = null)
,EMPDetailsEntity(id=4, FName=JKL, Active=YES, LName=LL'',L, Created=Wed Jun 16 20:20:20 EDT 2021, UpdatedBy = null)]
'

Select ID        = max(case when Item='id'        then value end)
      ,FirstName = max(case when Item='FName'     then value end)
      ,LastName  = max(case when Item='LName'     then value end)
      ,Active    = max(case when Item='Active'    then value end)
      ,CreateDt  = try_convert(date,stuff(stuff(max(case when Item='Created' then value end),11,13,''),1,4,''))
      ,UpdatedBy = case when max(case when Item='UpdatedBy' then value end) like '%null%' then null else max(case when Item='UpdatedBy' then value end) end
 From (
        Select Grp   = A.RetSeq
              ,Item  = left(B.RetVal,charindex('=',B.RetVal+'=')-1)
              ,Value = stuff(B.RetVal,1,charindex('=',B.RetVal+'='),'')
         From  [dbo].[tvf-Str-Parse](replace(replace(replace(replace(@S,'EMPDetailsEntity',''),')',''),']',''),'[',''),'(')  A
         Cross Apply [dbo].[tvf-Str-Parse](A.RetVal,', ') B
         Where len(A.RetVal)>25
      ) src
 Group By Grp

 

结果

感兴趣的功能

CREATE FUNCTION [dbo].[tvf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    Select RetSeq = row_number() over (order by 1/0)
          ,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From  ( values (cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.'))) as A(x)
    Cross Apply x.nodes('x') AS B(i)
);
--Usage: Select * from [dbo].[tvf-Str-Parse]('Dog,Cat,House,Car',',')

【讨论】:

真的很棒。谢谢#约翰。!它真的很好用。但是一个小问题,如果我必须从值中删除逗号/单引号。我们可以在同一个查询中执行还是使用函数来替换逗号或任何其他特殊字符。 @desi 这将是一个小调整。例如,在最后的 select ... 中,LastName = replace(replace(max(case when Item='LName' then value end),',',''),'''','') ... @desi 在 CROSS APPLY B 中这样做会很冒险。 @desi 三思而后行。如果您真的想从最终结果中删除引号和逗号... ,Value = replace(replace(stuff(B.RetVal,1,charindex('=',B.RetVal+'='),''), ',',''),'''','') .. @desi 这个 dbFiddle 说明了我的最后一条评论 dbfiddle.uk/…

以上是关于使用 SQL Server 将字符串数据块解析为表格数据集的主要内容,如果未能解决你的问题,请参考以下文章

将 XML 转换为表 SQL Server 2005

将 SQL 代码(作为字符串)转换为表 - 动态数据透视

SQL Server - 将标量函数转换为表值函数

SQL Server 2012将几个逗号分隔的值转换为表行/列

如何使用带有 sql server 2000 的 vb6 为表或 sp 获取“创建表”脚本

使用 SQL Server Management Studio 为表中的前 100 个值创建脚本