W ogólnym przypadku obsługa błędów bazy danych przebiega tak samo, jak w przypadku błędu środowiska wykonawczego. Wymagane jest napisanie kodu, który będzie przygotowany na błędy, jakie mogą wystąpić, oraz należy reagować na błędy, a nie pozostawiać tego środowisku wykonawczemu. Ogólnie możliwe błędy bazy danych mogą zostać podzielone na trzy kategorie: błędy połączenia, błędy składni SQL, oraz błędy naruszenia ograniczeń.
Błędy połączenia
Większość błędów baz danych to błędy połączenia, które mogą występować w każdej operacji. Istnieją strategie zapobiegania błędom połączeń, jednak rzadko dostępny jest prosty sposób odtwarzania po błędzie połączenia, gdy baza danych jest newralgiczną częścią aplikacji.
Większość błędów połączeń dotyczy sposobu oddziaływania środowiska wykonawczego z systemem operacyjnym, systemem plików i plikiem bazy danych. Na przykład: błąd połączenia występuje wówczas, gdy użytkownik nie ma uprawnienia do utworzenia pliku bazy danych w określonej lokalizacji w systemie plików. Poniższe strategie umożliwiają zapobieganie błędom połączeń:
-
Korzystanie z osobnych plików bazy danych dla poszczególnych użytkowników
-
Zamiast pojedynczego pliku bazy danych dla wszystkich użytkowników, którzy korzystają z aplikacji na pojedynczym komputerze, należy wyznaczyć dla każdego użytkownika osobny plik bazy danych. Plik należy zlokalizować w katalogu skojarzonym z kontem użytkownika. Na przykład: plik może znajdować się w katalogu zapisu aplikacji, w folderze dokumentów użytkownika, na pulpicie itp.
-
Użytkownicy innych typów
-
Aplikację należy przetestować z różnymi typami kont użytkowników na różnych systemach operacyjnych. Nie należy zakładać, że użytkownik ma uprawnienia administratora w komputerze. Ponadto nie należy przyjmować, że osoba, która zainstalowała aplikację to użytkownik, który korzysta z tej aplikacji.
-
Różne lokalizacje plików
-
Jeśli użytkownik ma możliwość określenia lokalizacji zapisu pliku bazy danych lub wyboru pliku do otwarcia, należy rozważyć różne lokalizacje plików, z których użytkownik będzie mógł korzystać. Ponadto należy rozważyć zdefiniowanie ograniczeń dotyczących miejsca zapisu (oraz miejsca otwierania) plików bazy danych. Na przykład: użytkownicy mogą mieć prawo do otwierania plików, które znajdują się w lokalizacji zapisu dla konta użytkownika.
Jeśli wystąpi błąd połączenia, najprawdopodobniej wystąpi przy pierwszej próbie utworzenia lub otwarcia bazy danych. Oznacza to, że użytkownik nie może wykonać żadnych operacji dotyczących bazy danych w aplikacji. W przypadku określonych typów błędów, takich jak błędy dotyczące uprawnień i praw odczytu, jedną możliwą techniką odtworzenia jest skopiowanie pliku bazy danych do innej lokalizacji. Aplikacja może skopiować plik bazy danych do innej lokalizacji, w której użytkownik ma uprawnienia do tworzenia i zapisywania w plikach — wówczas należy korzystać z tej lokalizacji.
Błędy składni
Błąd składni występuje wówczas, gdy instrukcja SQL jest sformatowana niepoprawnie, a aplikacja podejmuje próbę wykonania instrukcji. Instrukcje SQL lokalnej bazy danych są tworzone jako ciągi znaków, dlatego kontrola składni SQL w czasie kompilacji nie jest możliwa. W celu sprawdzenia składni instrukcji SQL należy wykonać te instrukcje. Poniższe strategie umożliwiają zapobieganie błędom składni SQL:
-
Dokładne testowanie wszystkich instrukcji SQL
-
Jeśli jest to możliwe, podczas programowania aplikacji należy osobno testować instrukcje SQL przed umieszczeniem ich jako tekstu instrukcji w kodzie aplikacji. Ponadto należy stosować podejście testowania kodu, takie jak testowanie jednostek, w celu utworzenia zestawu testów, które będą sprawdzały każdą możliwą opcję i wariant w kodzie.
-
Stosowanie parametrów instrukcji i unikanie konkatenacji (dynamiczne generowanie) SQL
-
Stosowanie parametrów i unikanie dynamicznie tworzonych instrukcji SQL oznacza, że ten sam tekst instrukcji SQL będzie używany przy każdym wykonaniu instrukcji. W konsekwencji znacznie łatwiej jest testować własne instrukcje i ograniczać możliwe warianty. Jeśli konieczne jest dynamiczne wygenerowanie instrukcji SQL, należy zminimalizować ilość sekcji generowanych dynamicznie. Ponadto należy uważnie sprawdzać poprawność danych wprowadzanych przez użytkownika, aby upewnić się, że dane nie spowodują błędu składni.
W celu odtworzenia po błędzie składni w aplikacji wymagana jest złożona logika, która będzie badała instrukcje SQL i naprawiała składnię. Na skutek przestrzegania powyższych instrukcji zapobiegania błędom składni kod będzie mógł identyfikować potencjalne błędy składni SQL (np. dane wprowadzone przez użytkownika użyte w instrukcji). W celu odtworzenia po błędzie składni należy pomóc użytkownikowi. Należy wskazać elementy do poprawy w celu poprawnego wykonania instrukcji.
Błędy naruszenia ograniczeń
Błąd naruszenia ograniczenia występuje wówczas, gdy instrukcja
INSERT
lub
UPDATE
podejmuje próbę dodania danych do kolumny. Ten błąd występuje wówczas, gdy nowe dane naruszają jedno ze zdefiniowanych ograniczeń dla tabeli lub kolumny. Zestaw możliwych ograniczeń obejmuje:
-
Ograniczenie unikalności
-
Określa, że jedna kolumna nie może zawierać zduplikowanych wartości (we wszystkich wierszach tabeli). I odwrotnie — jeśli wiele kolumn jest połączonych ograniczeniem unikalności, wówczas kombinacja wartości z tych kolumn nie może być duplikowana. Innymi słowy: w przypadku unikalnej kolumny lub kolumn każdy wiersz musi być inny.
-
Ograniczenie klucza podstawowego
-
W przypadku danych, na które ograniczenie zezwala i na które nie zezwala, ograniczenie klucza podstawowego jest takie samo, jak ograniczenie unikalności.
-
Ograniczenie „Not Null”
-
Określa, że kolumna nie może zawierać wartości
NULL
, co oznacza, że każdy wiersz kolumny musi zawierać wartość.
-
Ograniczenie Check
-
Umożliwia określenie dowolnego ograniczenia dla jednej lub większej liczby tabel. Popularnym ograniczeniem Check jest reguła określająca, że wartość kolumny musi należeć do określonego zakresu (np. że wartość w kolumnie liczbowej musi być większa od 0). Inny typ ograniczenia Check określa relacje między wartościami kolumn (np. wartość kolumny musi być różna od wartości w innej kolumnie, w tym samym wierszu).
-
Ograniczenie typu danych (powinowactwo kolumny)
-
Środowisko wykonawcze wymusza typ danych dla wartości kolumn, a próba zapisania w kolumnie wartości innego typu powoduje błąd. Jednak w wielu warunkach wartości są konwertowane w taki sposób, aby były zgodne z typem danych zadeklarowanym dla kolumny. Więcej informacji zawiera sekcja
Praca z typami danych w bazie danych
.
Środowisko wykonawcze nie narzuca ograniczeń na wartości kluczy obcych. Innymi słowy — wartości kluczy obcych nie muszą być zgodne z istniejącą wartością klucza podstawowego.
Oprócz predefiniowanych typów ograniczeń mechanizm środowiska wykonawczego SQL obsługuje wyzwalacze. Wyzwalacz jest podobny do modułu obsługi zdarzeń. Jest to predefiniowany zestaw instrukcji, które są wykonywane w przypadku wystąpienia określonej operacji. Na przykład: możliwe jest zdefiniowanie wyzwalacza, który będzie działał wówczas, gdy dane zostaną wstawione lub usunięte z określonej tabeli. Jednym z możliwych zastosowań wyzwalacza jest sprawdzanie zmian danych i wywoływanie błędu w przypadku niespełnienia określonych warunków. Dzięki temu wyzwalacz może służyć temu samemu celowi, co ograniczenie, a strategie zapobiegania błędom i odtwarzania po błędach przekroczenia ograniczeń będą również miały zastosowanie do błędów wygenerowanych przez wyzwalacze. Jednak identyfikator błędu wygenerowanego przez wyzwalacz jest inny niż identyfikator błędu przekroczenia ograniczeń.
Zestaw ograniczeń, który ma zastosowanie do określonej tabeli, jest określony podczas projektowania aplikacji. Świadome projektowanie ograniczeń ułatwia projektowanie aplikacji w taki sposób, aby zapobiegać błędom i odtwarzać po wystąpieniu błędów przekroczenia ograniczeń. Jednak przewidywanie i zapobieganie błędom przekroczenia ograniczeń jest trudne. Przewidywanie jest trudne, ponieważ błędy przekroczenia ograniczeń nie pojawiają się do czasu dodania danych aplikacji. Błędy naruszania ograniczeń występują w przypadku dodawania danych do bazy danych po jej utworzeniu. Te błędy często wynikają z relacji między nowymi danymi a danymi, które istnieją w bazie danych. Poniższe strategie umożliwiają zapobieganie wielu błędom ograniczeń:
-
Uważne planowanie struktury i ograniczeń bazy danych
-
Celem ograniczeń jest wymuszanie stosowania reguł aplikacji oraz ochrona integralności danych w bazie danych. Podczas planowania aplikacji należy rozważyć, strukturę bazy danych, która będzie obsługiwała aplikację. W ramach tego procesu należy określić reguły dla danych, np. to, czy niektóre wartości są wymagane, czy istnieje wartość domyślna, czy dozwolone są duplikaty wartości itp. Te reguły ułatwiają definiowanie ograniczeń dla bazy danych.
-
Jawne określanie nazw kolumn
-
Instrukcję
INSERT
można napisać bez jawnego określania kolumn, do których wprowadzane będą wartości, ale takie postępowanie wiąże się ze zbędnym ryzykiem. Jawne nazywanie kolumn, do których będą wprowadzane wartości, umożliwia automatyczne generowanie wartości, kolumn z wartościami domyślnymi oraz kolumn, które mogą zawierać wartości
NULL
. Ponadto takie postępowanie gwarantuje, że do wszystkich kolumn
NOT NULL
wprowadzane będą jawne wartości.
-
Korzystanie z wartości domyślnych
-
Jeśli jest to możliwe, wówczas przy każdej okazji określania ograniczenia
NOT NULL
dla kolumny należy określić domyślną wartość w definicji kolumny. Kod aplikacji może również określać wartości domyślne. Na przykład: kod może sprawdzać, czy zmienna String ma wartość
null
, a także przypisywać wartość przed użyciem jej w celu ustawienia wartości parametru instrukcji.
-
Sprawdzanie poprawności danych wprowadzanych przez użytkownika
-
Dane wprowadzane przez użytkownika należy sprawdzać z wyprzedzeniem, aby zapewnić zgodność tych danych z limitami określonymi przez ograniczenia, szczególnie w przypadku ograniczeń
NOT NULL
i
CHECK
. Oczywiście sprawdzenie ograniczenia
UNIQUE
jest trudniejsze, ponieważ w celu sprawdzenia należałoby wykonać zapytanie
SELECT
aby określić, czy dane są unikalne.
-
Stosowanie wyzwalaczy
-
Istnieje możliwość napisania wyzwalacza, który będzie sprawdzał poprawność (a w razie możliwości zastępował) wprowadzone dane lub będzie wykonywał inne czynności w celu poprawienia niepoprawnych danych. Ten sposób sprawdzania poprawności i poprawiania może zapobiegać występowaniu błędów naruszania ograniczeń.
W wielu przypadkach zapobieganie błędom naruszania ograniczeń jest dużo trudniejsze niż zapobieganie innym błędom. Na szczęście istnieje kilka strategii odtwarzania po wystąpieniu błędów naruszenia ograniczenia — strategie te obejmują sposoby, które nie powodują niestabilności aplikacji i nie powodują, że aplikacja staje się nie do użycia:
-
Stosowanie algorytmów konfliktów
-
Po zdefiniowaniu ograniczenia dla kolumny oraz utworzeniu instrukcji
INSERT
lub
UPDATE
istnieje możliwość określenia algorytmu konfliktu. Algorytm konfliktu definiuje operację, jaką wykonuje baza danych, gdy dojdzie do naruszenia ograniczenia. Istnieje kilka możliwych operacji, jakie może wykonać mechanizm bazy danych. Mechanizm bazy danych może zakończyć pojedynczą instrukcję lub całą transakcję. Może zignorować błąd. Może nawet usunąć stare dane i zastąpić je danymi, które kod próbuje zapisać.
Więcej informacji zawiera sekcja dotycząca klauzuli ON CONFLICT (algorytmów rozstrzygania konfliktów) w sekcji
Obsługa języka SQL w lokalnych bazach danych
.
-
Udostępnianie informacji zwrotnych na temat korekt
-
Zestaw ograniczeń, które mogą wpływać na określone polecenie SQL należy zidentyfikować z wyprzedzeniem. Dzięki temu możliwe jest przewidywanie błędów naruszenia ograniczeń, które może wywołać instrukcja. Dzięki tej wiedzy możliwe jest przygotowanie logiki aplikacji, która będzie reagowała na błąd naruszenia ograniczenia. Na przykład: załóżmy, że aplikacja zawiera formularz wprowadzania danych przeznaczony do wprowadzania nowych produktów. Jeśli kolumna nazwy produktu w bazie danych jest zdefiniowana z ograniczeniem
UNIQUE
, wówczas operacja wprowadzania wiersza nowego produktu do bazy danych może spowodować błąd naruszenia ograniczenia. W takim przypadku należy zaprojektować aplikację w taki sposób, aby przewidywała błąd naruszenia ograniczenia. Gdy wystąpi błąd, aplikacja ostrzega użytkownika, informując o tym, że określona nazwa produktu jest już używana. Aplikacja informuje również o konieczności wybrania innej nazwy. Inną możliwą reakcją jest zezwolenie użytkownikowi na wyświetlenie informacji o innym produkcie, o takiej samej nazwie.
|
|
|