OPENJSON - 修改语句以忽略字符串的第一部分
OPENJSON - modify statement to ignore first part of the string
我们从应用程序接收自动生成的电子邮件,并在它们到达收件箱时将其导出到我们的数据库。 table 称为 dbo.MailArchive
。
直到最近,电子邮件的正文一直是这样的...
Status: Completed
Successful actions count: 250
Page load count: 250
...除了不同的数字和状态。 注意Page load count后空行有一个回车return
整个数据被写入一个名为 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
为了澄清,这是顶部的一个新行,该行末尾的回车 return,以及新行和 [= 之间的空白行上的回车 return 16=] 行。目前,还没有一致的方法来预测哪些电子邮件会随新行进入,哪些不会。
我如何修改我们的 OPENJSON
声明,如果第一行存在于正文中,skip/ignore 它并解析第 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
Returns
ID Status Action PageCnt
1 Completed 250 250
注意:如果要查看 NULL,请使用 OUTER APPLY
我们从应用程序接收自动生成的电子邮件,并在它们到达收件箱时将其导出到我们的数据库。 table 称为 dbo.MailArchive
。
直到最近,电子邮件的正文一直是这样的...
Status: Completed
Successful actions count: 250
Page load count: 250
...除了不同的数字和状态。 注意Page load count后空行有一个回车return
整个数据被写入一个名为 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
为了澄清,这是顶部的一个新行,该行末尾的回车 return,以及新行和 [= 之间的空白行上的回车 return 16=] 行。目前,还没有一致的方法来预测哪些电子邮件会随新行进入,哪些不会。
我如何修改我们的 OPENJSON
声明,如果第一行存在于正文中,skip/ignore 它并解析第 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
Returns
ID Status Action PageCnt
1 Completed 250 250
注意:如果要查看 NULL,请使用 OUTER APPLY