Sdílet prostřednictvím


Porovnání výrazů (XQuery)

platí pro:SQL Server

XQuery poskytuje následující typy relačních operátorů:

  • Obecné relační operátory

  • Operátory porovnání hodnot

  • Operátory porovnání uzlů

  • Operátory porovnání pořadí uzlů

Obecné relační operátory

Obecné relační operátory lze použít k porovnání atomických hodnot, sekvencí nebo jakékoli kombinace těchto dvou.

Obecné operátory jsou definovány v následující tabulce.

Operátor Popis
= Rovný
!= Nerovná se
< Méně než
> Větší než
<= Menší než nebo rovno
>= Větší než nebo rovno

Při porovnávání dvou sekvencí pomocí obecných relačních operátorů a hodnota existuje ve druhé sekvenci, která porovnává hodnotu True s hodnotou v první sekvenci, celkový výsledek je True. Jinak je false. Například (1, 2, 3) = (3, 4) je Pravda, protože hodnota 3 se zobrazí v obou sekvencích.

declare @x xml  
set @x=''  
select @x.query('(1,2,3) = (3,4)')    

Porovnání očekává, že hodnoty jsou srovnatelné typy. Konkrétně jsou staticky kontrolovány. U číselných porovnání může dojít k povýšení číselného typu. Pokud se například desetinná hodnota 10 porovná s dvojitou hodnotou 1e1, změní se desetinná hodnota na dvojitou. Všimněte si, že to může vytvořit neexaktní výsledky, protože dvojité porovnání nemůže být přesné.

Pokud je jedna z hodnot nezadaná, přetypuje se na typ druhé hodnoty. V následujícím příkladu se hodnota 7 považuje za celé číslo. Před porovnáním se netypová hodnota /a[1] převede na celé číslo. Celočíselné porovnání vrátí hodnotu True.

declare @x xml  
set @x='<a>6</a>'  
select @x.query('/a[1] < 7')  

Pokud se naopak netypová hodnota porovná s řetězcem nebo jinou nezatypovanou hodnotou, přetypuje se na xs:string. V následujícím dotazu se řetězec 6 porovná s řetězcem "17". Následující dotaz vrátí hodnotu False z důvodu porovnání řetězců.

declare @x xml  
set @x='<a>6</a>'  
select @x.query('/a[1] < "17"')  

Následující dotaz vrátí obrázky modelu produktu s malou velikostí z katalogu produktů poskytovaného v ukázkové databázi AdventureWorks. Dotaz porovnává sekvenci atomických hodnot vrácených PD:ProductDescription/PD:Picture/PD:Size s jednou sekvencí "small". Pokud je porovnání Pravda, vrátí prvek <Picture>.

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS PD)  
SELECT CatalogDescription.query('         
    for $P in /PD:ProductDescription/PD:Picture[PD:Size = "small"]         
    return $P') as Result         
FROM   Production.ProductModel         
WHERE  ProductModelID=19         

Následující dotaz porovnává posloupnost telefonních čísel v <číslo> prvků s řetězcovým literálem "112-111-1111". Dotaz porovná sekvenci prvků telefonního čísla ve sloupci AdditionalContactInfo a určí, jestli v dokumentu existuje konkrétní telefonní číslo pro konkrétního zákazníka.

WITH XMLNAMESPACES (  
  'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes' AS act,  
  'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo' AS aci)  
  
SELECT AdditionalContactInfo.value('         
   /aci:AdditionalContactInfo//act:telephoneNumber/act:number = "112-111-1111"', 'nvarchar(10)') as Result         
FROM Person.Contact         
WHERE ContactID=1         

Dotaz vrátí hodnotu True. To znamená, že číslo v dokumentu existuje. Následující dotaz je mírně upravená verze předchozího dotazu. V tomto dotazu se hodnoty telefonních čísel načtených z dokumentu porovnávají s posloupností dvou hodnot telefonních čísel. Pokud je porovnání True, vrátí se <číslo> prvek.

WITH XMLNAMESPACES (  
  'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes' AS act,  
  'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo' AS aci)  
  
SELECT AdditionalContactInfo.query('         
  if (/aci:AdditionalContactInfo//act:telephoneNumber/act:number = ("222-222-2222","112-111-1111"))         
  then          
     /aci:AdditionalContactInfo//act:telephoneNumber/act:number         
  else         
    ()') as Result         
FROM Person.Contact         
WHERE ContactID=1  
  

Toto je výsledek:

\<act:number   
  xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">  
    111-111-1111  
\</act:number>  
\<act:number   
  xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">  
    112-111-1111  
\</act:number>   

Operátory porovnání hodnot

K porovnání atomických hodnot se používají operátory porovnání hodnot. Všimněte si, že v dotazech můžete místo operátorů porovnání hodnot použít obecné relační operátory.

Operátory porovnání hodnot jsou definovány v následující tabulce.

Operátor Popis
Eq Rovný
severovýchod Nerovná se
lt Méně než
Gt Větší než
Le Menší než nebo rovno
germanium Větší než nebo rovno

Pokud obě hodnoty porovnávají stejné hodnoty podle zvoleného operátoru, výraz vrátí hodnotu True. V opačném případě vrátí hodnotu False. Pokud je některou z hodnot prázdná sekvence, výsledek výrazu je False.

Tyto operátory pracují pouze na atomických hodnotách singleton. To znamená, že nemůžete určit posloupnost jako jeden z operandů.

Například následující dotaz načte prvky <Picture> pro produktový model, kde je velikost obrázku malá:

SELECT CatalogDescription.query('         
              declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";         
              for $P in /PD:ProductDescription/PD:Picture[PD:Size eq "small"]         
              return         
                    $P         
             ') as Result         
FROM Production.ProductModel         
WHERE ProductModelID=19         

Všimněte si následujících věcí z předchozího dotazu:

  • declare namespace definuje předponu oboru názvů, která se následně použije v dotazu.

  • Hodnota elementu <Size> se porovnává se zadanou atomovou hodnotou "small".

  • Všimněte si, že protože operátory hodnot pracují pouze na atomických hodnotách, funkce data() se implicitně používá k načtení hodnoty uzlu. To znamená, že data($P/PD:Size) eq "small" vytvoří stejný výsledek.

Toto je výsledek:

\<PD:Picture   
  xmlns:PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription">  
  \<PD:Angle>front\</PD:Angle>  
  \<PD:Size>small\</PD:Size>  
  \<PD:ProductPhotoID>31\</PD:ProductPhotoID>  
\</PD:Picture>  

Všimněte si, že pravidla povýšení typu pro porovnání hodnot jsou stejná jako u obecných porovnání. SQL Server také používá stejná pravidla přetypování pro nezatypované hodnoty při porovnávání hodnot, které používá při obecných porovnáních. Naproti tomu pravidla ve specifikaci XQuery vždy přetypují nezatypovanou hodnotu na xs:string během porovnání hodnot.

Operátor porovnání uzlů

Operátor porovnání uzlů, je, se vztahuje pouze na typy uzlů. Výsledek, který vrátí, označuje, zda dva uzly předané jako operandy představují stejný uzel ve zdrojovém dokumentu. Tento operátor vrátí hodnotu True, pokud jsou dva operandy stejný uzel. V opačném případě vrátí hodnotu False.

Následující dotaz zkontroluje, jestli je umístění pracovního centra 10 první v procesu výroby konkrétního modelu produktu.

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions' AS AWMI)  
  
SELECT ProductModelID, Instructions.query('         
    if (  (//AWMI:root/AWMI:Location[@LocationID=10])[1]         
          is          
          (//AWMI:root/AWMI:Location[1])[1] )          
    then         
          <Result>equal</Result>         
    else         
          <Result>Not-equal</Result>         
         ') as Result         
FROM Production.ProductModel         
WHERE ProductModelID=7           

Toto je výsledek:

ProductModelID       Result          
-------------- --------------------------  
7              <Result>equal</Result>      

Operátory porovnání pořadí uzlů

Operátory porovnání pořadí uzlů porovnávají páry uzlů na základě jejich pozic v dokumentu.

Jedná se o porovnání, která se provádí na základě pořadí dokumentů:

  • <<: operand 1 předchází operandu 2 v pořadí dokumentu.

  • >>: operand 1 dodržovat operand 2 v pořadí dokumentu.

Následující dotaz vrátí hodnotu True, pokud popis katalogu produktů obsahuje prvek <Warranty> před elementem <Maintenance> v objednávce dokumentu pro konkrétní produkt.

WITH XMLNAMESPACES (  
  'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS PD,  
  'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain' AS WM)  
  
SELECT CatalogDescription.value('  
     (/PD:ProductDescription/PD:Features/WM:Warranty)[1] <<   
           (/PD:ProductDescription/PD:Features/WM:Maintenance)[1]', 'nvarchar(10)') as Result  
FROM  Production.ProductModel  
where ProductModelID=19  

Všimněte si následujících věcí z předchozího dotazu:

  • Metoda value() datového typu xmlse používá v dotazu.

  • Logický výsledek dotazu se převede na nvarchar(10) a vrátí se.

  • Dotaz vrátí hodnotu True.

Viz také

type System (XQuery)
výrazy XQuery