OPEN JSON - изменить инструкцию, чтобы игнорировать первую часть строки - PullRequest
0 голосов
/ 14 января 2020

Мы получаем автоматически сгенерированные электронные письма из приложения и экспортируем их в нашу базу данных по мере их поступления в папку «Входящие». Таблица называется 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?

1 Ответ

1 голос
/ 14 января 2020

Поскольку ваши данные имеют новые начальные и конечные строки, я думаю, что простая агрегация в сочетании с string_split() и CROSS APPLY будет более эффективной, чем мой предыдущий XML ответ и текущий JSON подход

Пример или 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

Примечание: использовать OUTER APPLY, если вы хотите видеть NULL

...