【问题标题】:OPENJSON - modify statement to ignore first part of the stringOPENJSON - 修改语句以忽略字符串的第一部分
【发布时间】:2020-01-13 22:12:43
【问题描述】:

我们从应用程序接收自动生成的电子邮件,并在它们到达收件箱时将其导出到我们的数据库。该表名为dbo.MailArchive

直到最近,电子邮件的正文一直是这样的......

Status: Completed
Successful actions count: 250
Page load count: 250

...除了不同的数字和状态。 注意页面加载计数后的空白行有回车。

整个数据被写入一个名为 Mail_Body 的字段 - 然后我们使用 OPENJSON 运行以下语句,将这些行解析为记录中它们自己的列:

DECLARE @PI varchar(7) = '%[^' + CHAR(13) + CHAR(10) + ']%';

SELECT j.Status,
       j.Successful_Actions_Count,
       j.Page_Load_Count
FROM dbo.MailArchive m
     CROSS APPLY(VALUES(REVERSE(m.Mail_Body),PATINDEX(@PI,REVERSE(m.Mail_Body)))) PI(SY,I)
     CROSS APPLY(VALUES(REVERSE(STUFF(PI.SY,1,PI.I,''))))S(FixedString)
     CROSS APPLY OPENJSON (CONCAT('{"', REPLACE(REPLACE(S.FixedString, ': ', '":"'), CHAR(13) + CHAR(10), '","'), '"}')) 
                 WITH (Status varchar(100) '$.Status',
                       Successful_Actions_Count int '$."Successful actions count"',
                       Page_Load_Count int '$."Page load count"') j;

从今天开始,某些电子邮件的正文如下所示:

Agent did not meet defined success criteria on this run.

Status: Completed
Successful actions count: 250
Page load count: 250

为了澄清,这是顶部的一个新行,该行末尾的回车符,以及新行和Status 行之间的空白行上的回车符。目前,还没有一致的方法来预测哪些电子邮件会与这个新行一起出现,哪些不会。

如何修改我们的OPENJSON 语句,如果正文中存在第一行,则跳过/忽略它并解析第 3 到第 5 行,否则只需执行我上面的操作?或者也许更好地适应未来,总是忽略Status这个词之前的所有内容?

【问题讨论】:

    标签: sql json sql-server sql-server-2017


    【解决方案1】:

    由于您的数据具有新的前导行和尾随行,我认为与 string_split()CROSS APPLY 一致的简单聚合将比我之前的 XML 答案和当前的 JSON 方法更有效

    示例or dbFiddle

    Select A.ID
          ,Status  = stuff(Pos1,1,charindex(':',Pos1),'')
          ,Action  = try_convert(int,stuff(Pos2,1,charindex(':',Pos2),''))
          ,PageCnt = try_convert(int,stuff(Pos3,1,charindex(':',Pos3),''))
     From  YourTable A
     Cross Apply (
                   Select [Pos1] = max(case when Value like 'Status:%' then value end)
                         ,[Pos2] = max(case when Value like '%actions count:%' then value end)
                         ,[Pos3] = max(case when Value like 'Page load count:%' then value end)
                    From  string_split(SomeCol,char(10))
                 ) B
    

    退货

    ID   Status     Action  PageCnt
    1    Completed  250     250
    

    注意:如果您想查看 NULL,请使用 OUTER APPLY

    【讨论】:

      猜你喜欢
      • 2016-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多