W przypadku pobierania danych unikodowych z SQL Server (kolumny typu nchar, nvarchar i ntext) do aplikacji Perl na Win32 (ActivePerl 5.8.x) za pomocą DBI przez ODBC (moduł DBD::ODBC w wersji 1.13) tracone są wszystkie znaki nie mieszczące się w kodowaniu Latin-*. Problem nie jest może nowy, ale jego rozwiązania może być kłopotliwe - dlatego postanowiłem o nim napisać.
DBI na DBD::ODBC błędne interpretuje typy danych nchar, nvarchar, ntext - w związku z czym zmienne skalarne, do których trafiają dane unikodowe, nie mają ustawionej flagi utf8 i w logice interpretera nie są poprawnymi unikodowymi łańcuchami znaków. Przykładowo: tekst w cyrylicy zostanie zapisany do pamięci programu jako ciąg znaków zapytania w ASCII (??????) i tak też Perl będzie go przetwarzał. W przypadku innych modułów DBD (np. DBD::ADO) lub innych providerów (np. Win32::SqlServer) problem nie występuje lub możliwe jest dokonanie ustawień, które go wyeliminują.
Moduł DBD::ODBC z różnych powodów w praktyce nie jest już rozwijany, dlatego nie warto liczyć na nową wersję, w której poprawione zostaną wyżej opisane problemy. Do wersji 1.13 istnieje nieoficjalny patch, który wprowadza do modułu prawidłową obsługę danych unikodowych pobieranych z niektórych baz danych - w tym SQL Server 2000 i 2005. Do zastosowania patcha wymagana jest ręczna rekompilacja DBD::ODBC.
Instalację patcha zalecam wykonać w następujący sposób:
1. Najpierw należy pobrać kod modułu z CPAN (link poniżej lub plik do pobrania
stÄ…d).
2. Następnie rozpakowujemy archiwum (zostanie utworzony katalog
DBD-ODBC-1.13, w którym przeprowadzimy dalsze czynności).
3. Jeżeli moduł DBD::ODBC jest obecnie zainstalowany, zalecane jest jego usunięcie. W konsolowej wersji PPM najpierw szukamy wpisu modułu za pomocą polecenia
query, a następnie usuwamy za pomocą komendy
remove.
4. Następnie pobieramy plik z kodem patchującym (link poniżej lub plik do pobrania
stÄ…d) i wrzucamy go do rozpakowanego w pkt 2 katalogu.
5. Uruchamiamy polecenie (możliwość wykonywania którego w środowisku Windows trzeba zapewnić sobie samemu przez zainstalowanie pakietu narzędzi unixowych np. UnxUtils - link poniżej):
patch -p1 < unicode-patch.txt
6. Następnie przystępujemy do standardowej ręcznej kompilacji modułu. Zakładam, że w systemie zainstalowane jest SDK i jakaś wersja kompilatora C/C++ (choćby darmowa - Visual C++ Express), dostępne jest więc też narzędzie
nmake. Kompilację najlepiej przeprowadzić z linii komend IDE/kompilatora (np. Visual Studio 2005 Command Prompt), wtedy nie będzie problemu ze ścieżkami i zmiennymi środowiskowymi. Upraszczając, kompilacja polega na kolejnym uruchomieniu następujących komend:
perl Makefile.pl
nmake
nmake test
nmake install
Jeżeli wszystko przebiegnie prawidłowo, to w pkt 5 zostanie zainstalowany i podpięty spachowany moduł DBD::ODBC, który prawidłowo obsłuży dane unikodowe pobierane z SQL Server. Czasem trzeba trochę powalczyć podczas kompilacji, ale najczęściej odbywa się ona bez większych problemów.
Więcej informacji i pobieranie:
CPAN: DBD-ODBC-1.13
DBD::ODBC-1.13 Unicode Patch
UnxUtils homepage
Visual C++ Express
Download: .NET Framework 2.0 Software Development Kit (SDK) (x86)