Zine.net online

Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc
w Szukaj

dev2dev

XML-owe przypadki – dziwne zachowanie ‘every…satisfies’

Przygotowując przykłady do sesji “XML w SQL Server 2008” na portalu Virtual Study w cyklu SQL nie tylko dla orłów organizowanym wspólnie z Polish SQL Server User Group trafiłem na ciekawy przypadek z użyciem konstrukcji ‘every … satisfies’ w metodzie query zastosowanej do obiektu typu XML.

Ale aby dojść do sedna sprawy trzeba zdefiniować dwa pojęcia:

  • sekwencje,
  • sposób wartościowania logicznego w XQuery.

I. Sekwencje

Na początek definicja pustej sekwencji. Wygląda to tak:

()

Sekwencję tworzy się poprzez użycie operatora przecinkowego do: pustej sekwencji, typów atomowych oraz węzłów. Przykładowe poprawne sekwencje mogą wyglądać tak:

(1, ”dwa”, 3.0,0000004, 5e+0, ())

((), /,  /x)

Pusta sekwencja jest pomijana w wynikowej sekwencji.

Nie można w jednej sekwencji użyć typów atomowych i węzłów (generuje to błąd heterogenicznych sekwencji):

(1, ”dwa”, 3.0,0000004, 5e+0, /x)

II. Wartościowanie logiczne w XQuery

Wartościowanie logiczne w XQuery w SQL Server jest zawężone (nie można na przykład wartościować logicznie wartości typu xs:string oraz wartości typu numerycznego, chociaż specyfikacja XQuery przywiduje taką możliwość). Wartościowanie w SQL Server ma zastosowanie do:

  • atomowej wartości logicznej (funkcje true() i false() generują odpowiednie wartości logiczne odpowiadające wartości prawy i fałszu logicznego, funkcja not() generuje zaprzeczenie logiczne)
  • pustej sekwencji
  • sekwencji węzłów
W SQL Server wartościowanie logiczne zwraca true gdy:
  • sekwencja zawiera węzły lub gdy jest wartość logiczna true
  • false w przeciwnym wypadku

III. Przećwiczmy to na przykładach.

Na początek zobaczmy jak funkcja not wartościuje pustą sekwencję:

select CAST('' as xml).query('not(())')

W wyniku dostajemy wynik true, co świadczy, że pusta sekwencja jest wartościowana jak false.

Konstrukcja 'every ... satisfies' zwraca true gdy wszystkie elementy z sekwencji są wartościowane na true.

Aby się o tym przekonać zobaczmy jak zadziała takie zapytanie:

select CAST('' as xml).query('every $x in (true(), true()) satisfies $x')
select CAST('' as xml).query('every $x in (false(), true()) satisfies $x')
select CAST('' as xml).query('every $x in (true(), false()) satisfies $x')
select CAST('' as xml).query('every $x in (false(), false()) satisfies $x')

Wyniki są jak najbardziej poprawne, czyli true, false, false, false.

W takim razie zobaczmy czy puste elementy  sekwencji za instancjami węzłów:

select CAST('' as xml).query('every $x in (() instance of node(), () instance of node()) satisfies ($x)')

Nie są, zapytanie zwraca false. 

To może jeszcze jedno zapytanie sprawdzające z ilu węzłów składa się pusta sekwencja:

select CAST('' as xml).query('every $x in (count(()), count(())) satisfies $x > 0')

Jest OK, nie zawiera żadnych węzłów.

W takim razie zobaczmy jaki rezultat będzie takiego zapytania:

select CAST('' as xml).query('every $x in (()) satisfies $x')

O dziwo, pomimo, że sekwencja zawiera sekwencję pustą to powyższe zapytanie zwraca również true.

Hmm, dziwne.  OK, wobec tego zobaczmy co zwróci to zapytanie:

select CAST('' as xml).query('every $x in ((), ()) satisfies $x')

True! Dlaczego?

Wobec tego zróbmy zapytanie z zaprzeczeniem

select CAST('' as xml).query('every $x in ((), ()) satisfies not($x)')

Znowu true! Ale przecież zaprzeczyliśmy warunek dla satisfies!

Czy gdzieś popełniam błąd? Dwa powyższe zapytania są równoważne tym zapytaniom:

select CAST('' as xml).query('every $x in () satisfies ($x)')

select CAST('' as xml).query('every $x in () satisfies not($x)')

ponieważ SQL Server pomija pute sekwencje występujące w sekwencji i w takim wypadku nie dochodzi do wartościowania warunku po satisfies ponieważ sekwencja nie zawiera żadnego elementu. Ale czy w takim wypadku nie powinna być zwraca wartość false? Morze to rzecz gustu albo tak po prostu ma być "by design"?
Opublikowane 14 maja 2010 21:41 przez marekpow

Komentarze:

 

dotnetomaniak.pl said:

Dziękujemy za publikację - Trackback z dotnetomaniak.pl

maja 15, 2010 07:13
Komentarze anonimowe wyłączone
W oparciu o Community Server (Personal Edition), Telligent Systems