다음을 통해 공유


경로 식 - 조건자 지정

적용 대상:SQL Server

XQuery의 경로 식 항목에서 설명한 대로 경로 식의 축 단계에는 다음 구성 요소가 포함됩니다.

  • 입니다.

  • 노드 테스트입니다. 자세한 내용은 경로 식 단계에서 노드 테스트 지정을 참조 하세요.

  • 0개 이상의 조건자. 스테이지 범주는 선택 사항입니다.

선택적 조건자는 경로 식에서 축 단계의 세 번째 부분입니다.

조건자

조건자는 지정된 테스트를 적용하여 노드 시퀀스를 필터링하는 데 사용됩니다. 조건자 식은 대괄호로 묶이고 경로 식의 마지막 노드에 바인딩됩니다.

예를 들어 다음과 같이 xml 데이터 형식의 SQL 매개 변수 값(x)이 선언되어 있다고 가정합니다.

declare @x xml  
set @x = '  
<People>  
  <Person>  
    <Name>John</Name>  
    <Age>24</Age>  
  </Person>  
  <Person>  
    <Name>Goofy</Name>  
    <Age>54</Age>  
  </Person>  
  <Person>  
    <Name>Daffy</Name>  
    <Age>30</Age>  
  </Person>  
</People>  
'  

이 경우 다음은 3개의 서로 다른 노드 수준에서 조건자 값 [1]을 사용하는 유효한 식입니다.

select @x.query('/People/Person/Name[1]')  
select @x.query('/People/Person[1]/Name')  
select @x.query('/People[1]/Person/Name')  

각 경우에 조건자는 적용되는 경로 식의 노드에 바인딩됩니다. 예를 들어 첫 번째 경로 식은 각 /People/Person 노드 내의 첫 번째 <Name> 요소를 선택하고 제공된 XML 인스턴스를 사용하여 다음을 반환합니다.

<Name>John</Name><Name>Goofy</Name><Name>Daffy</Name>  

그러나 두 번째 경로 식은 첫 번째 /People/Person 노드 아래에 있는 모든 <Name> 요소를 선택합니다. 따라서 다음을 반환합니다.

<Name>John</Name>  

괄호를 사용하여 조건자의 평가 순서를 변경할 수도 있습니다. 예를 들어 다음 식에서 괄호 집합은 조건자 [1]에서 (/People/Person/Name)의 경로를 구분하는 데 사용됩니다.

select @x.query('(/People/Person/Name)[1]')  

이 예제에서는 조건자가 적용되는 순서가 변경됩니다. 이는 묶은 경로가 먼저 평가되고(/People/Person/Name) 조건자 [1] 연산자가 묶인 경로와 일치하는 모든 노드가 포함된 집합에 적용되기 때문입니다. 괄호를 사용하지 않으면 첫 번째 경로 식 예와 마찬가지로 [1]이 child::Name 노드 테스트에서와 같이 다르게 적용될 것입니다.

한정자 및 조건자

수량자는 조건자 자체의 중괄호 내에서 두 번 이상 사용하고 추가할 수 있습니다. 예를 들어 이전 예제를 사용하면 복잡한 조건자 하위 식 내에서 둘 이상의 수량자를 사용할 수 있습니다.

select @x.query('/People/Person[contains(Name[1], "J") and xs:integer(Age[1]) < 40]/Name/text()')  

조건자 식의 결과는 부울 값으로 변환되며 조건자 진리 값이라고 합니다. 조건자의 진리 값이 True인 시퀀스의 노드만 결과에 반환됩니다. 다른 모든 노드는 삭제됩니다.

예를 들어 다음 경로 식은 두 번째 단계에서 조건자를 포함합니다.

/child::root/child::Location[attribute::LocationID=10]  

이 조건자에서 지정한 조건은 모든 요소 노드 자식에 <Location> 적용됩니다. 그 결과 LocationID 특성 값이 10인 해당 작업 센터 위치만 반환됩니다.

이전 경로 식은 다음 SELECT 문에서 실행됩니다.

SELECT Instructions.query('  
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
 /child::AWMI:root/child::AWMI:Location[attribute::LocationID=10]  
')  
FROM Production.ProductModel  
WHERE ProductModelID=7  

조건자 진리 값 계산

다음 규칙은 XQuery 사양에 따라 조건자 진리 값을 결정하기 위해 적용됩니다.

  1. 조건자 식의 값이 비어 있는 시퀀스인 경우 해당 조건자의 진리 값은 False입니다.

    예시:

    SELECT Instructions.query('  
    declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
     /child::AWMI:root/child::AWMI:Location[attribute::LotSize]  
    ')  
    FROM Production.ProductModel  
    WHERE ProductModelID=7  
    

    이 쿼리의 경로 식은 LotSize 특성이 지정된 요소 노드만 <Location> 반환합니다. 조건자가 특정 <Location>항목에 대해 빈 시퀀스를 반환하는 경우 해당 작업 센터 위치는 결과에 반환되지 않습니다.

  2. 조건자 값은 xs:integer, xs:Boolean 또는 node*만 될 수 있습니다. node*의 경우 노드가 있으면 조건자가 True로 계산되고 빈 시퀀스에 대해서는 False가 됩니다. double 및 float 유형과 같은 다른 모든 숫자 유형은 정적 형식 지정 오류를 발생시킵니다. 식의 조건자 진리 값은 결과 정수가 컨텍스트 위치의 값과 같은 경우에만 True입니다. 또한 정수 리터럴 값과 last() 함수만 필터링된 단계 식의 카디널리티를 1로 줄입니다.

    예를 들어 다음 쿼리는 요소의 세 번째 자식 요소 노드를 검색합니다 <Features> .

    SELECT CatalogDescription.query('  
    declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
    declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
     /child::PD:ProductDescription/child::PD:Features/child::*[3]  
    ')  
    FROM Production.ProductModel  
    WHERE ProductModelID=19  
    

    이전 쿼리의 다음 사항에 유의하세요:

    • 식의 세 번째 단계는 값이 3인 조건자 식을 지정합니다. 따라서 이 식의 조건자 진리 값은 컨텍스트 위치가 3인 노드에 대해서만 True입니다.

    • 세 번째 단계에서는 노드 테스트의 모든 노드를 나타내는 와일드카드 문자(*)도 지정합니다. 그러나 조건자는 노드를 필터링하고 세 번째 위치에 있는 노드만 반환합니다.

    • 쿼리는 문서 루트의 <Features> 요소 자식 요소 자식 요소 자식의 <ProductDescription> 세 번째 자식 요소 노드를 반환합니다.

  3. 조건자 식의 값이 부울 형식의 단순 형식 값인 경우 조건자 진리 값은 조건자 식의 값과 같습니다.

    예를 들어 다음 쿼리는 XML 인스턴스인 고객 설문 조사 XML 인스턴스를 보유하는 xml 형식 변수에 대해 지정됩니다. 쿼리는 자식이 있는 고객을 검색합니다. 이 쿼리에서는 HasChildren<1>/HasChildren<입니다>.

    declare @x xml  
    set @x='  
    <Survey>  
      <Customer CustomerID="1" >  
      <Age>27</Age>  
      <Income>20000</Income>  
      <HasChildren>1</HasChildren>  
      </Customer>  
      <Customer CustomerID="2" >  
      <Age>27</Age>  
      <Income>20000</Income>  
      <HasChildren>0</HasChildren>  
      </Customer>  
    </Survey>  
    '  
    declare @y xml  
    set @y = @x.query('  
      for $c in /child::Survey/child::Customer[( child::HasChildren[1] cast as xs:boolean ? )]  
      return   
          <CustomerWithChildren>  
              { $c/attribute::CustomerID }  
          </CustomerWithChildren>  
    ')  
    select @y  
    

    이전 쿼리의 다음 사항에 유의하세요:

    • for 루프의 식에는 두 단계가 있으며 두 번째 단계는 조건자를 지정합니다. 이 조건자의 값은 부울 유형의 값입니다. 이 값이 True이면 조건자의 진리 값도 True입니다.

    • 쿼리는 문서 루트의 <Customer> Survey< 요소 자식에 대한 조건자 값이 True>인 요소 자식을 반환합니다. 다음은 결과입니다.

      <CustomerWithChildren CustomerID="1"/>   
      
  4. 조건자 식의 값이 하나 이상의 노드를 포함하는 시퀀스인 경우 조건자 진리 값은 True입니다.

예를 들어 다음 쿼리는 XML 카탈로그 설명에 wm 접두사와 연결된 네임스페이스에서 요소의<Features> 자식 요소인 하나 이상의 기능을 포함하는 제품 모델에 대한 ProductModelID를 검색합니다.

SELECT ProductModelID  
FROM   Production.ProductModel  
WHERE CatalogDescription.exist('  
             declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
             declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
             /child::PD:ProductDescription/child::PD:Features[wm:*]  
             ') = 1  

이전 쿼리의 다음 사항에 유의하세요:

  • WHERE 절은 exist() 메서드(XML 데이터 형식)를 지정합니다.

  • exist() 메서드 내의 경로 식은 두 번째 단계에서 조건자를 지정합니다. 조건자 식이 적어도 하나의 기능이 포함된 시퀀스를 반환하는 경우 이 조건자 식의 진리 값은 True입니다. 이 경우 exist() 메서드가 True를 반환하므로 ProductModelID가 반환됩니다.

정적 형식 지정 및 조건자 필터

조건자는 식의 정적으로 유추된 형식에도 영향을 줄 수 있습니다. 정수 리터럴 값과 last() 함수는 필터링된 단계 식의 카디널리티를 최대 1로 줄입니다.