31/01/2010

"Decimal byte array constructor requires an array of length four containing valid decimal bytes"

Home

"Decimal byte array constructor requires an array of length four containing valid decimal bytes"

Z takim błędem spotkałem się ostatnio pisząc kod komunikujący się z bazą danych. Niestety ale błąd ten miał również dwie utrudniające jego poprawienie właściwości. Po pierwsze pojawiał się na kilku komputerach ale nie na moim. No cóż syndrom "a u mnie działa" zdarza się każdemu. Po drugie kod w jakim występował zdawał się wyglądać całkowicie niewinnie:
DataSet ds = New DataSet

OleDbDataAdapter adapter = New OleDbDataAdapter
adapter.SelectCommand = New OleDbCommand(Command, Connection)

adapter.Fill(ds)
Dokładniej mówiąc wyjątek pojawiał sie przy wywołaniu metody Fill. Kiedy zapytałem wyszukiwarkę o treść komunikatu znalazłem kilkanaście forów z pytaniami dotyczącymi tego błędy w kontekście komunikacji z różnymi bazami danych (ja używam bazy danych Informix). Niestety prawie wszystkie zadane pytania zostały bez odpowiedzi. Znalazłem jednak wypowiedź sugerującą, że błąd pojawia się jeśli w zapytaniu użyto funkcji agregujących.

Zapytanie, którego ja użyłem zawierało całkiem sporo przykładów użycia funkcji agregujących, postanowiłem więc usunąć je z zapytania i zobaczyć co się stanie. W wyniku modyfikacji zapytania wyjątek nie pojawił się. Miałem więc już jakąś wskazówkę co robić dalej. W następnym kroku dodawałem do zapytania kolejne odwołania do funkcji agregujących żeby zobaczyć, które dokładnie spowoduje błąd.

Po kilku próbach znalazłem kłopotliwy fragment zapytania. Wyglądał on tak:
SELECT ..., SUM(Col1) - Sum(Col2), ... 
W tym momencie przypomniałem sobie pewną rzecz i już wiedziałem jak rozwiązać problem. Tak jak napisałem wcześniej błąd nie pojawiał się na komputerze, na którym pracowałem. Dane, które pobrałem z bazy danych mogłem, więc wyświetlić na kontrolce gridowej. Kiedy zrobiłem to po raz pierwszy zauważyłem, że w niektórych kolumnach liczby prezentowane są z bardzo dużą precyzję pomimo, że na poziomie bazy danych użyto typu DECIMAL o precyzji 2. Problem rozwiązałem wymuszając po prostu odpowiednie formatowanie. Teraz jednak okazało się, że kolumny o "dziwnym" formatowaniu na mojej maszynie pokrywały się z przykładami użycia funckji, które powodowały błąd na innych stacjach.

Pierwszy wniosek jest taki, że wynik operacji arytmetycznych na rezultatach działania funkcji agregujących może mieć wyższą precyzję niż by to wynikało z typu kolumn. W przypadku niektórych działań arytmetycznych ma to oczywiście sens, chociaż nie w przypadku odejmowania czy dodawania. Ale mniejsza o tym. Istotne jest to, że z powodu zwiększonej precyzji nie jest potem możliwe skonstruowanie wartości typu decimal i generowany jest wyjątek. Rozwiązanie jest proste. Trzeba zaokrąglić wynik:
SELECT ..., ROUND(SUM(COl1) - Sum(Col2), 2), ... 
Z tego co się dowiedziałem pomóc może również użycie nowszych sterowników OLEDB. Z drugiej strony na moim komputerze zainstalowana jest taka sama wersja sterowników jak na innych. Różnica jest taka, że ja używam Windows 7 ale trudno powiedzieć czy to ma jakiś wpływ. W każdym razie pytanie czemu błąd nie pojawia się na wszystkich stacjach pozostaje otwarte.

06/01/2010

Uruchamianie aplikacji na 64 bitach

Home

Pierwszy wpis w nowym roku 2010 będzie dotyczył zagadnienia uruchamiania aplikacji .Net'owych na maszynach 64 bitowy. W większości przypadków nie ma z tym żadnego problemu. W końcu IL jest przenośny. Problemy zaczynają się kiedy chcemy wykorzystać w swojej aplikacji biblioteki 32 bitowe. Niestety ale nie jest możliwe aby proces 64 bitowy używał bibliotek 32 bitowych i na odwrót. Przeważnie nie mamy również możliwości przekompilowania biblioteki, z której korzystamy. Ja spotkałem się z tym problem uruchamiając aplikację, która do połączenia z bazą danych korzystała ze sterownika ODBC. W czasie jej uruchomienia pojawiał się komunikat:

Dostawca 'Ifxoledbc.2' nie jest zarejestrowany na lokalnym komputerze.

Komunikat mnie zdziwił ponieważ byłem pewny, że dostawca jest zarejestrowany. Przypomniałem sobie jednak, że jest to sterownik 32 bitowy. Jak sobie poradziłem?

Ogólnie są dwa rozwiązania tego problemu. Po pierwsze można w właściwościach projektu ustawić opcję Target CPU na X86. Domyślna wartość to Any CPU. Jeśli z jakichś powodów nie możemy zrekompilować aplikacji możemy skorzystać z programu corflags. Jest on instalowany razem z Visual Studio i pozwala przełączyć aplikację w 32 bitowy tryb pracy np.:

corflags /32bit+ aplikacja

W razie potrzeby ponownego przełączenia na 64 bitowy tryb pracy używamy następującej składni:

corflags /32bit- aplikacja

28/12/2009

BadImageFormatException i TFS

Home

Przed paroma dniami zainstalowałem na swoim komputerze najnowszą wersję serwera TFS czyli Microsoft Visual Studio Team Foundation Server 2010 Beta 2. Instalacja przebiegła szybko i bezproblemowo z dokładnością do tego, że wcześniej musiałem jeszcze zainstalować SQL Server 2008 oraz, co trochę dziwne dla mnie, najnowszy Service Pack dla systemu Windows Vista.

Kiedy instalacja dobiegła końca uruchomiłem konsolę Team Foundation Administration Console, dalej użyłem kreatora konfiguracji i pomyślałem, że będę mógł się cieszyć nową zabawką. Niestety próba podłączenia się do serwera, czy to z poziomu VS 2010 czy to z poziomu programu Microsoft Test and Lab Manager, kończyła się błędem Unable to connect to Team Foundation Server.

Próbując rozwiązać problem dotarłem do systemowego logu zdarzeń. Tam znalazłem kilka podejrzanie wyglądających zdarzeń, których źródło nazywało się TFS Services. Aby upewnić się co do ich pochodzenia zatrzymałem pulę aplikacyjną Microsoft Team Foundation Server Application Pool, do której należą usługi TFS. Odczekałem chwilę i ponownie ją uruchomiłem. Zaglądam ponownie do logu zdarzeń i znajduję serię 3 komunikatów, których czas wystąpienia zgadzał się z czasem uruchomienia puli aplikacyjnej. Dwa pierwsze komunikaty miały źródło o nazwie TFS Services, a trzeci ASP.NET 4.0.21006.0. W trzecim komunikacie znalazłem interesującą informację o wystąpieniu nieobsłużonego wyjątku BadImageFormatException.

Jeszcze chwila szukania i znajduję rozwiązanie. Okazało się, że błąd był spowodowany nieprawidłową konfiguracja wspomnianej puli aplikacyjnej Microsoft Team Foundation Server Application Pool. Miała ona włączoną opcję Włącz aplikacje 32 bitowe podczas gdy ja korzystam z wersji 64 bitowej. Po wyłączeniu tej flagi problem ustąpił i wszystko zaczęło działać.

23/12/2009

Życzenie świąteczne

Home

Wszystkim czytelnikom i czytelniczkom składam życzenia wesołych i radosnych Świąt Bożego Narodzenia.

Serdecznie pozdrawiam
Michał Komorowski

18/12/2009

"Dzikie żądze"

Home

W pracy komputer, na studiach doktoranckich komputer... Nie ulega wątpliwości, że dużą część dnia spędzam wpatrzony w monitor. Dlatego tak bardzo lubię wyjść z żoną na miasto, a jedną z naszych ulubionych rozrywek jest dobra komedia w teatrze.

Przedwczoraj odwiedziliśmy ponownie teatr "Bajka" na deskach, którego można teraz oglądać brytyjską sztukę "Dzikie żądze". Opowiada ona o małżeństwie Państwa Griffin. On bogaty przemysłowiec, ona lekko znudzona. Aby ratować małżeństwo postanawiają na nowo rozbudzić w sobie żądzę... Więcej z fabuły nie zdradzę, dodam tylko, że jest nieprzewidywalna, pełna zwrotów akcji i po prostu przezabawna. Przez większość przedstawienia nie robiłem nic innego tylko się śmiałem. W pewnym momencie nawet aktorzy nie mogli się powstrzymać od śmiechu. Byłbym jednak niesprawiedliwy gdybym nie powiedział, że bardzo szybko się powstrzymali.

Zaskakujące było też zakończenie wieczoru. Jeden z aktorów zaprosił na scenę młodą parę, która wygrała bilety w konkursie radiowym żeby zrobić sobie z nimi zdjęcie. Jak się okazało był to tylko "niecny" wybieg. Gdzieś znalazły się kwiaty i za chwilę chłopak na kolanach prosił swoją wybrankę o rękę :) Brawo za odwagę!

W teatrze "Bajka" po raz kolejny spędziłem wspaniały wieczór i z czystym sumieniem mogę go polecić każdemu. Teatr naprawdę nie gryzie.