我们从应用程序接收自动生成的电子邮件,然后在它们到达收件箱时将它们导出到数据库中。该表称为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
之前的所有内容?
由于您的数据具有新的开头和结尾行,因此我认为与string_split()
和CROSS APPLY
一起进行简单的聚合比我以前的XML答案和当前的JSON方法更有效
示例
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