O formatach liczb i dat
Rzecz niby powszechnie znana ale często przeaczana.
Każdy program korzystający z Oracle i używający jakichkolwiek dat lub liczb zmiennoprzecinkowych powinien zdefiniować, w jakim formacie chce je otrzymywać.
Najprościej umieścić gdzieś na początku programu polecenia typu
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'; ALTER SESSION SET NLS_NUMERIC_CHARACTERS='. ';
dobierając oczywiście odpowiadający potrzebom aplikacji format (powyższy przykład ustawia format daty typu 2001-03-12 17:32:48 i format liczb zmiennoprzecinkowych z oddzielaniem części ułamkowej kropką i bez separowania tysięcy). Sam zazwyczaj realizuję powyższe polecenia natychmiast po podłączeniu się do bazy danych.
Zapomnienie o powyższym jest proszeniem się o kłopoty. Już kilka razy zetknąłem się z sytuacją, w której program działa, przechodzi testy a następnie nieoczekiwanie zaczyna zwracać bezsensowne wyniki, zgłaszać błędy itp. Bo autor testował zapomniawszy o ustawieniu zmiennej NLS_LANG, dostawał liczby rzeczywiste z częścią ułamkową oddzieloną kropką a po zainstalowaniu, w środowisku z ustawionymi 'polskimi' preferencjami nagle zaczęły przychodzić z przecinkiem. Albo odwrotnie, ktoś przypadkiem zepsuł zmienne środowiskowe w instalacji produkcyjnej, aplikacja dostała daty w odwróconym formacie i dokonała kompletnie błędnego przetwarzania. Itp. Problem najmocniej dotyczy programowania przy użyciu języków skryptowych (jeśli zmiennej perlowej przypiszemy napis 3,50, jak najbardziej uda się nam używać go później jako liczby - tylko że będzie to liczba 3) ale nawet programując z wykorzystaniem OCI nieraz pobieramy liczby lub daty jako tekst.
Powyższe cechy Oracle można też ustawiać przy pomocy zmiennych środowiskowych. Ale bezpieczniej jest, gdy skonfiguruje je sobie sam program - w taki sposób, jakiego sam wymaga. Nawet jeśli tworzymy program z założenia 'wielojęzykowy', wykorzystujący locale do rozpoznawania wymagań prezentacyjnych, często bezpieczniej jest pobierać dane z bazy danych w kontrolowany sposób i ewentualnie reformatować je później.
komentarze obsługiwane przez Disqus