I.
Wprowadzenie do  języków zapytań (1)
II.
Wprowadzenie do  języków zapytań (2)
III.
Pojęcia obiektowości w bazach danych (1)
IV.
Pojęcia obiektowości w bazach danych (2)
V.
Podstawy semantyczne języków zapytań
VI.
Modele składu obiektów
VII.
Stos środowisk, rezultaty zapytań, funkcja nested
VIII.
Język SBQL (Stack-Based Query Language) (1)
IX.
X.
Dalsze własności SBQL
XI.
Operatory order by i group by
XII.
Przetwarzanie struktur nieregularnych
XIII.
Rozszerzenie języków zapytań o konstrukcje imperatywne
XIV.
Procedury, procedury funkcyjne, metody, reguły zakresu
XV.
Parametry procedur i metod, procedury rekurencyjne, optymalizacja poprzez modyfikację zapytań
  Wstęp
  1. Parametry procedur, funkcji i metod
  2. Procedury rekurencyjne
  3. Optymalizacja poprzez modyfikację zapytań
  Podsumowanie
  Zadania

 

2. Procedury rekurencyjne

Podejście stosowe zakłada rekurencję jako własność oczywistą. Umożliwienie określania parametrów procedur w postaci zapytań oraz zwracania wyniku procedur w postaci dowolnej wartości dziedziny Rezultat stwarza nową jakość, która dotychczas była kwalifikowana jako własność "inteligentna", specyficzna dla dedukcyjnych baz danych. Za pomocą rekurencyjnych procedur można bez trudu osiągnąć efekty omawiane poprzednio dla tranzytywnych domknięć oraz równań stałopunktowych. Jak się okazuje, mimo różnic składniowych i semantycznych, są to mechanizmy porównywalne pragmatycznie. Z doświadczeń autora wynika, że procedury rekurencyjne są bardziej zrozumiałe dla powszechnego programisty, być może wskutek praktyki edukacyjnej.

P15.8.

Patrz Rys.71. Procedura Podczęści ma parametr mojeCzęści bedący bagiem referencji do części. Procedura zwraca bag z referencjami do wszystkich podczęści części wymienionych w parametrze. Duplikaty w wyniku nie są usuwane. Przy transmisji parametrów przyjmujemy metodę ścisłego wołania przez wartość.

procedure Podczęści( mojeCzęści) {
     return if not exists(mojeCzęści) then
          bag{}
     else
          bag( mojeCzęści, Podczęści(mojeCzęści.składnik.prowadziDo.Część))}

Procedura zwraca części występujące w argumencie, następnie nawiguje do ich bezpośrednich podczęści i wywołuje sama siebie. W momencie, gdy dany obiekt nie będzie miał podobiektu Składnik, argument procedury Podczęści będzie pusty, co zakończy jej działanie.

Podaj nazwy wszystkich części detalicznych składających się na samolot Boening 767:

distinct
( Podczęści( Część where nazwa = "Boening 767" )
     where rodzaj = "detal").nazwa

 

P15.9.

Patrz Rys.71. Procedura PodczęściIle ma parametr mojeCzęściIle w postaci zapytania zwracającego bag struktur struct{ c(r), ile(v) }, gdzie c(r) jest binderem, w którym r jest referencją do obiektu część, ile(v) jest binderem w którym v jest liczbą nieujemną. Liczba v ustala ilość części z referencją r. Procedura zwraca bag struct{c(r1), ile(v1)} specyfikujący podczęści wszystkich części wymienionych w parametrze procedury: r1 jest referencją do podczęści, zaś v1 jest ilością tych podczęści niezbędnych do złożenia ilości części wymienionych w parametrze procedury. Duplikaty zwracanych referencji nie są usuwane, jak również nie są sumowane ilości podczęści wynikające z różnych dróg dotarcia do danej podczęści w strukturze część/podczęść.

procedure PodczęściIle( mojeCzęściIle) {
     return if not exists(mojeCzęściIle) then
          bag{} else bag( mojeCzęściIle,
          (mojeCzęściIle.PodczęściIle(c.(składnik.(
               (prowadziDo.Część) as c, (ile * ilość) as ile)))))}

Jeżeli bag będący argumentem procedury jest niepusty, to procedura zwraca wszystkie elementy tego bagu, plus elementy zawierające informację o ich podczęściach. W tym celu konieczne jest przemnożenie ilości danej części w argumencie procedury z ilością jej bezpośredniej podczęści.

Planuje się wyprodukowanie 68 samolotów B767 oraz 135 samolotów B747. W tej chwili jest przygotowywana umowa z kooperantem dostarczającym wkręty o nazwie "M5x70" niezbędne do produkcji samolotów. Ile wkrętów należy zamówić?

sum(
PodczęśćIle( bag((Część where nazwa = "B767") as c, 68 as ile),
     (Część where nazwa = "B747") as c, 135 as ile))).
          where c.nazwa = "M5x70").ile)

 

P15.10.

Obiekty Osoba mają atrybuty nazwisko, rokUr (rok urodzenia), żyje (z wartością boolowską) oraz są powiązane związkami rodzinnymi matka, ojciec, syn, córka, zaimplementowanymi jako obiekty pointerowe umieszczone wewnątrz obiektów Osoba. Procedura Przodek zwraca wszystkich przodków osób zakomunikowanych jako parametr. Procedura Następca zwraca wszystkich następców osób zakomunikowanych jako parametr. Każda osoba jest jednocześnie swoim przodkiem i następcą.

procedure Przodek( mojeOsoby) {
      return if not exists(mojeOsoby) then bag{}
          else distinct( bag(mojeOsoby
               Przodek(mojeOsoby.(matka È ojciec).Osoba)))}

procedure Następca( mojeOsoby) {
      return if not exists(mojeOsoby) then bag{}
          else distinct( bag(mojeOsoby
               Następca (mojeOsoby.(syn È córka).Osoba)))}

Podaj nazwisko i rok urodzenia wszystkich żyjących kuzynów Kowalskiego, którzy są od niego młodsi:

(((Osoba where nazwisko = "Kowalski") as kow) join
(Następca(Przodek( kow )) as kuzyn)
where (kow.rokUr > kuzyn.rokUr and kuzyn.żyje)).
(kuzyn.(nazwisko, rokUr))


Copyrights © 2006 PJWSTK
Materiały zostały opracowane w PJWSTK w projekcie współfinansowanym ze środków EFS.