08/05/2011

Float(1) = Float(24) ???

Home

Jakiś czas temu pracowałem nad komponentem, który odpowiadał za generacją tabel w bazie danych na podstawie zadanej definicji. Dodatkowo kod ten potrafił wykryć różnicę pomiędzy definicją, a faktyczną strukturą tabeli w bazie danych i poinformować o tym użytkownika. Przynajmniej w teorii bo w praktyce czasami twierdził, że definicja nie jest spójna ze stanem faktycznym w bazie danych chociaż na pierwszy rzut oka wyglądała, że jest.

Wspomniany kod zawierał oczywiście kilka błędów, które udało mi się szybko poprawić ale jeden zapadł mi w pamięci. Pewnie dlatego, że jego znalezienie było trochę trudniejsze. Błąd ten pojawiał się kiedy definicja tabeli zawierała kolumnę typu float. W takim wypadku komponent zawsze twierdził, że definicja i strukturą tabeli w bazie danych są inne.

Diagnozę błędu rozpocząłem od przygotowania definicji trywialnej tabeli z jedną kolumną typu float o zadanej precyzji 10. Komponent wygenerował tabelę przy użyciu poniższej komendy DDL i oczywiście stwierdził, że coś jest nie tak.
CREATE TABLE TestTable
(
 SomeNumber float(10) NULL
) 
Do wykrywaniu różnic pomiędzy definicją, a stanem bazy danych skorzystałem z widoków systemowych, a w szczególności z widoku sys.all_columns. Postanowiłem, więc zobaczyć jak wygląda wiersz odpowiadający kolumnie SomeNumber i otrzymałem taki wynik:

object_id name column_id system_type_id user_type_id max_length precision scale ...
2137058649 SomeNumber 1 59 59 4 24 0 ...

Moją uwagę od razu zwróciła zawartość kolumny precision równa 24. Zgodnie z definicja powinno być natomiast 10. Chwila konsternacji, szybkie spojrzenie do dokumentacji i wszystko okazało się jasne. SQL Server ze względu na zgodność ze standardem ISO pozwala napisać float(10), float(20) itp. ale wewnętrznie wartości od 1 do 24 traktuje jak 24, a wartości od 25 do 53 jako 53. Po uwzględnieniu tej informacji komponent zaczął działać prawidłowo.

0 comments:

Post a Comment