SQL Server: выбор определенных значений из произвольных узлов в выводе данных XML - Ответ - PullRequest
0 голосов
/ 04 июня 2019

У меня есть XML-вывод из машинного тестирования, который выглядит следующим образом: мне нужно извлечь конкретные данные из узла, который я не могу указать для каждого теста:

<TestResult>
  <MethodResult
     X
     X
     X
    <StepResult name = "FlowError" status = "ProductFailure"> 
      <ActualValue>
        <Number value = "3" />
      </ActualValue>
      <Limit constraint Type = "In Range" name = "FlowError">
        <Low>
          <Number value = "5" />
        </Low>
        <High>
          <Number value = "6" />
        </High>
      </Limit>
      <Error source="X" code="Y" mesg="Failed for X; Value was 3, expected [5 to 6]/> 
    </StepResult>
  </MethodResult>
</TestResults>

Как вы можете догадаться, есть много других результатов шага, обозначенных знаком X, которые я просто не смог полностью перечислить. В каждом тестовом случае есть вероятность того, что тестируемая машина может выйти из строя, и в узле, соответствующем тестовому примеру (давление, расход, утечка и т. Д., Будет сгенерирована ошибка)

Мне нужно найти способ произвольного вывода параметров сбоя при сбое машины. Обратите внимание, что каждый раз, когда машина выходит из строя, она выводит статус «ProductFailure» для последнего узла StepResult. А затем мне нужно извлечь нижний предел, верхний предел, а также фактическое значение.

Пока что я могу извлечь фактическое значение, указав узел, используя следующий скрипт:

Select

f.ResultXML.value('(/TestResults/MethodResult/StepResult[@name="FlowError"]/ActualValue/Number)[1]/@value', 'varchar(max)') As "Actual Value"

From TestResult.ResultData

Однако приведенный выше код будет выводить значения только при сбое в работе машины. Ошибка давления и ошибка утечки, например, не будут отображать значение (которое мне также нужно)

Я подумал, что могу просто изменить @Name на @Status и попросить его искать «ProductFailure», это даст мне результаты неудачного шага каждый раз, вместо того, чтобы я указывал FlowError, но вместо этого он каждый раз возвращает Null.

Мне интересно, как я могу извлечь строки для фактического значения, верхнего предела и нижнего предела без необходимости указывать фактическое сообщение об ошибке "FlowError" или любые другие ошибки.

Заранее спасибо

Edit:

Добавление фактического XML из базы данных [MSPTestResult]. [MSPTestResult]. [ResultData], который я буду удалять позже из-за потенциально конфиденциальной информации.

Edit:

Вопрос ответил, проблема заключалась в том, что мой запрос должен был указать каждый отдельный узел, который уникален, например, StepResult [@ name = "Ошибка продукта"], а затем перейти в Limit [@constraint type = "In Range"] и т. Д.

1 Ответ

0 голосов
/ 04 июня 2019

Я не уверен, почему вы получаете сообщение об ошибке status="productFailure", так как у меня все это работает:

declare @xml xml
set @xml=convert(xml,'<TestResult>
<MethodResult>
 <StepResult />
 <StepResult />
 <StepResult />
 <StepResult name = "FlowError" status = "ProductFailure"> 
  <ActualValue>
    <Number value = "3" />
  </ActualValue>
  <Limit constraint_Type = "In Range" name="FlowError">
    <Low>
      <Number value = "5" />
    </Low>
    <High>
      <Number value = "6" />
    </High>
  </Limit>
  <Error source = "X" code = "Y" mesg = "Failed for X Value was 3 expected 5 to 6" /> 
</StepResult>
</MethodResult>
</TestResult>')
select @xml.query('/TestResult/MethodResult/StepResult[@status="ProductFailure"]')
select @xml.value('(/TestResult/MethodResult/StepResult[@status="ProductFailure"]/ActualValue/Number)[1]/@value', 'varchar(10)') As "Actual Value"
select @xml.value('(/TestResult/MethodResult/StepResult[@status="ProductFailure"]/Limit/Low/Number)[1]/@value', 'varchar(10)') As "Low Value"
select @xml.value('(/TestResult/MethodResult/StepResult[@status="ProductFailure"]/Limit/High/Number)[1]/@value', 'varchar(10)') As "High Value"

Результаты, которые я вижу, представляют собой полную FlowError (определенную проверкой состояния), а затем три значения для фактических, высоких и низких значений.

РЕДАКТИРОВАТЬ: (После того, как весь фактический XML был опубликован) XML немного отличается от исходного примера, и узел ProductFailure не имеет ни узла max и min, ни узла /ActualValue/Number.

В следующих двух строках извлекаются значения для ActualValue и Less Than

select @xml.value('(/TestResults/MethodResult/StepResult[@status="ProductFailure"]/ActualValue/Flow)[1]/@value', 'varchar(10)') As "Actual Value"
select @xml.value('(/TestResults/MethodResult/StepResult[@status="ProductFailure"]/Limit[@constraintType="LessThan"]/Value/Flow)[1]/@value', 'varchar(10)') As "Less Than"

Если разные типы ошибок имеют разные типы контента, вам нужно будет либо попробовать каждую возможную комбинацию, либо найти какой-то другой способ их идентификации, возможно позиционный, или, возможно, получив все атрибуты @value и отработав мин. / max / фактические из их относительных значений.

...