LAB: Integracja z RDBMS

Celem laboratorium jest pokazanie możlwości integracji maszyny wnioskującej SWI Prolog z systemami zarządzania relacyjnymi bazami danych (RDBMS).

Interackja taka jest możliwa z wykorzystaniem ODBC.

1 Konfiguracja ODBC

Aby móc skorzystać z tzw. źródła danych ODBC, należy w domowym katalogu utworzyć plik o nazwie .odbc.ini oraz umieścić w nim poniższą treść:

[prolog]
Description		= PostgreSQL Unicode
Driver		= PostgreSQL Unicode
Trace		= No
TraceFile		= 
Database		= prolog
Servername		= borg.ia.agh.edu.pl
Username                =
Password                =
Port		        = 5432
Protocol		= 6.4
ReadOnly		= No
RowVersioning		= No
ShowSystemTables	= No
ShowOidColumn		= No
FakeOidIndex		= No
ConnSettings		= 

Uwaga:

  1. Wartości pól Username oraz Password będą podane przez prowadzącego na zajęciach.
  2. Prawa dostępu do pliku .odbc.ini powinny być ustawione na 600.

Powyższe działania konfigurują źródło danych ODBC o nazwie prolog ([prolog]). Źródło to jest skojarzone z systemem zarządzania relacyjnymi bazami danych PostgreSQL działającym na serwerze borg.ia.agh.edu.pl, a konkretnie z bazą danych o nazwie prolog (Database).

Ćwiczenie

Sprawdź, czy źródło danych jest poprawnie skonfigurowane. W tym celu uruchom narzędzie isql umożlwiające wykonywanie zapytań w języku SQL na źródle ODBC:

isql prolog

Jeżeli połączenie powiodło się zostanie wyświetlony stosowny komunikat:

~$ isql prolog
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL>

Następnie wykonaj proste zapytanie np. SELECT nazwa FROM kompozycje;. Rezultat powinien być zbliżony do tego poniżej:

SQL> SELECT nazwa FROM kompozycje;
+-----------------------------------------+
| nazwa                                   |
+-----------------------------------------+
| Bukiet 1                                |
| Bukiet 2                                |
| Bukiet 3                                |
| Kosz 1                                  |
| Kosz rozyczek                           |
| Kosz mix                                |
| Kompozycja suszona                      |
| Koszyk gozdzikowy                       |
| Hiacynty w koszyku                      |
| Biala azalia                            |
| Rozowa azalia                           |
| Orchidea rozowa                         |
| Kosz z azalia                           |
| Wiazanka czerwona                       |
| Bukiecik serc                           |
| Ikebana z rozami                        |
| Kwitnacy kosz                           |
| Sloneczniki z lilia                     |
| Strelicje                               |
| Anturium latem                          |
+-----------------------------------------+
SQLRowCount returns 20
20 rows fetched
SQL>

2 ODBC w SWI-Prolog

SWI Prolog umożliwia wykonywanie zapytań na źródłach ODBC. Rezultaty zapytania (pojedynczy wiersz) uzgodniane są ze wskazanymi szukanymi. Wartości kolejnych kolejnych wierszy dostępne są poprzez mechanizm nawrotów.

Przed wykonaniem zapytania należy nawiązać połączenie ze skonfigurowanym źródłem ODBC.

Dokumentacja dotycząca predykatów obsługujących połączenia ODBC z bazami danych.

3 Połączenia

Do nawiązaywania połączenia ze źródłem danych ODBC służy predykat odbc_connect/3. Pierwszym argumentem jest nazwa źródła danych ODBC (w poniższym przykładzie prolog), drugim jest identyfikator połączenia, trzecim opcje połączenia, np.

odbc_connect('prolog', Polaczenie,
             [open(once)
           ]).

Przed zakończeniem korzystania z połączenia ze źródłem danych należy wywołać predykat odbc_disconnect/1, którego argumentem musi być identyfikator połączenia (zakładając, że szukana Polaczenie jest uzgodniona z wartością będącą identyfikatorem połączenia utworzonym za pomocą odbc_connect/3):

odbc_disconnect(Polaczenie).

Zamiast identyfikatora połączenia można użyć synonimu połączenia, korzystając z opcji alias:

?- odbc_connect('prolog', _,
             [ alias(prolog),
               open(once)
           ]).

Tak otwarte połączenie można zakończyć:

?- odbc_disconnect(prolog).

4 Schemat Bazy Danych

Schemat bazy danych, dostępnej jako źródło danych prolog przedstawiony jest poniżej.

CREATE TABLE klienci (
    idklienta VARCHAR(10) NOT NULL,
    haslo VARCHAR(10) NOT NULL,
    nazwa VARCHAR(40) NOT NULL,
    miasto VARCHAR(40) NOT NULL,
    kod CHAR(6) NOT NULL,
    adres VARCHAR(40) NOT NULL,
    email VARCHAR(40),
    telefon VARCHAR(16) NOT NULL,
    fax VARCHAR(16),
    nip CHAR(13),
    regon CHAR(9)
);
 
CREATE TABLE kompozycje (
    idkompozycji CHAR(5) NOT NULL,
    nazwa VARCHAR(40) NOT NULL,
    opis VARCHAR(100),
    cena NUMERIC(7,2),
    minimum INTEGER,
    stan INTEGER
);
 
 
CREATE TABLE odbiorcy (
    idodbiorcy INTEGER NOT NULL,
    nazwa VARCHAR(40) NOT NULL,
    miasto VARCHAR(40) NOT NULL,
    kod CHAR(6) NOT NULL,
    adres VARCHAR(60) NOT NULL
);
 
 
CREATE TABLE zamowienia (
    idzamowienia INTEGER NOT NULL,
    idklienta VARCHAR(10) NOT NULL,
    idodbiorcy INTEGER NOT NULL,
    idkompozycji CHAR(5) NOT NULL,
    termin DATE NOT NULL,
    cena NUMERIC(7,2),
    zaplacone BOOLEAN,
    uwagi VARCHAR(200)
);
 
 
CREATE TABLE historia (
    idzamowienia INTEGER NOT NULL,
    idklienta VARCHAR(10),
    idkompozycji CHAR(5),
    wartosc NUMERIC(7,2),
    termin DATE
);

Kompletny skrypt z schematem i danymi.

5 Wykonywanie zapytań

Zapytania można realizować korzystając z predykatu odbc_query/4 (albo odbc_query/3, patrz dokumentacja). Pierwszym argumentem jest identyfikator połączenia, drugim zapytanie w języku SQL, trzecim rezultat zapytania w postaci termu row/n (argumenty predykatu row/n będą uzgodnione z wartościami w kolejnych kolumnach zwaracanych przez zapytanie), czwartym lista dodatkowych opcji.

Przykładowe zapytanie zwracające jako wartości szukanych Nazwa, Email wartości kolumn nazwa i email tabeli klienci będzi wyglądało następująco:

?- odbc_query(prolog, 'SELECT nazwa, email FROM klienci' ,row(Nazwa, Email), []).

Ostatni argument odbc_query/4 umożliwia przekazanie dodatkowych opcji, m.in. konwersje typów pomiędzy SQL a Prologiem (patrz dokumentacja).

Ćwiczenie

  1. Otwórz połączenie do bazy danych korzystając ze źródła danych prolog.
  2. Wykonaj następujące zapytanie SQL: SELECT SUM(cena), miasto FROM zamowienia JOIN odbiorcy USING (idodbiorcy) GROUP BY miasto;, przeglądnij wyniki.
  3. Zamknij połączenie.

6 Proste zapytania

Ćwiczenie

Zaimplementuj:

  1. predykat op/0 otwierający połączenie ze źródłem danych prolog,
  2. predykat cl/0 zamykający w/w połączenie,
  3. predykat kompozycje/2 udostępniający informacje o kompozycji tj. identyfikator oraz cenę. Uwaga: może być konieczne zastosowanie konwersji typów, użyteczny predykat: atom_number/2 (patrz dokumentacja).

Przetestuj działanie w/w predykatów.

7 Złożone przetwarzanie

Częstą rozterką kupojącego jest: mam określoną sumę pieniędzy, ale co moge za to kupić np.:

  • Jakie i ile kompozycji można kupić za 200 zł?

Takie zapytanie jest trudne lub wręcz niemożliwe do zaimplementowania za pomocą SQL.

Ćwiczenie

Zaimplementuj predykat jakieza/2, tak aby zapytanie:

?- jakieza(200,X).

uzgadniało X z listą nazw identyfikatorów kompozycji kwiatowych, które można kupić mając do dyspozyji 200 zł. Uwaga: predykat winien być niedeternistyczny, umożliwiać znalezienie alternatywnych rozwiązań.

8 Samodzielny program

Wykorzystaj kod z poprzedniego ćwiczenia.

Ćwiczenie

Zmodyfikuj kod programu z poprzedniego ćwiczenia, tak aby stanowił samodzielną aplikację. Program po skonsultowaniu, powinien zapytać o kwotę i wyświetlić wszystkie możlwie kombinacje kompozycji kwiatowych, które można za podaną kwotę kupić, podając: identyfikator kompozycji, nazwę oraz cenę.

Uwagi, komentarze, propozycje

Laboratorium jest za krótkie. Zostaje ok. 30 minut wolnego czasu.

Szymon Świerkosz

pl/prolog/prolog_lab/prolog_lab_rdbms.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0