Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Funkcja (UDF) zawierająca polskie znaki
Forum PHP.pl > Forum > Bazy danych > MySQL
slightyboy
Witam,

ostatnio zainteresowałem się funkcjami i procedurami MySQL. Stwierdziłem, że ułatwiają życie i przy okazji pomagają przy optymalizacji. Postanowiłem więc przenieść część funkcji PHP bezpośrednio do MySQL, by nie musieć w trakcie parsowania danych pobranych z bazy wywoływać kolejno tych samych funkcji. Gdzie leży problem? Otóż niektóre z nich (owych funkcji) zwracają ciągi tekstowe zawierające polskie znaki. Niestety ciągi zwracane przez funkcje MySQL zamiast owych znaków zawierają jedynie krzaczki. Przykładowa funkcja:

  1. CREATE FUNCTION testMeNow (p char(1))
  2. RETURNS char(20)
  3. RETURN 'ąęćłóżź';


Rezultat dla jej wykonania:
Kod
ąęćłóżź


Więcej tłumaczyć nie trzeba. Oczywiście próbowałem znaleźć rozwiązanie, Google'owałem, szukałem, próbowałem używać funkcji MySQL CAST oraz CONVERT, jednak bez pozytywnych rezultatów, krzaczki po prostu przybierały inny format, ale nadal pozostawały krzaczkami. Co więcej próbowałem również zmieniać kodowanie pliku z funkcją (ładuję ją z poziomu konsoli poprzez "SOURCE"), niestety bez skutku. Próbowałem nawet pobierać wynik tej funkcji we wszystkich (36) dostępnych w MySQL kodowaniach (do konwersji używałem funkcji CONVERT), również bez rezultatu.

Jeśli ktoś zna rozwiązanie albo chociaż potrafi mnie na nie naprowadzić, bardzo proszę o pomoc. Stworzyłem również temat na forum dev.mysql.com, więc proszę mnie tam nie odsyłać. smile.gif
erix
A jaki masz zestaw znaków dla połączenia? Przez co wywołujesz zapytanie?
slightyboy
W bazie wszystko ustawione na UTF8, zapytanie wykonuję póki co z poziomu PhpMyAdmin'a.

Troszkę się męczyłem by zrozumieć zasady ustawień kodowania dla bazy danych (poradniki, tutoriale, metoda prób i błędów), więc nie sądzę by w tym leżał problem (dotąd nie pojawił się problem z kodowaniem), ale oczywiście mogę się mylić. smile.gif
erix
To powiedz, jakie masz te parametry ustawione. [;

Bo skoro masz rzekomo ustawione kodowanie, to powinno być ok.
slightyboy
Kodowanie bazy (tabeli): utf8
Metoda porównywania: utf8_polish_ci

Dodam jeszcze, że kiedy funkcja ma zwracać rekord z bazy danych, polskie literki wyświetlają się prawidłowo. Ustawianie "SET NAMES" przed wywołaniem funkcji również nic nie daje. dry.gif


EDIT (03:07): Cóż, uporałem się z problemem we własnym zakresie, oczywiście nie obyło się bez Google. Dla ciekawych podam źródła, których pomoc była nieoceniona:

http://bugs.mysql.com/bug.php?id=28567
http://www.mysqlperformanceblog.com/2007/1...-mess-in-mysql/ (zwłaszcza post numer 19 - tamcy'ego)
http://www.bothernomore.com/2008/12/16/cha...-encoding-hell/ (finalne rozwiązanie)

Rozwiązanie natomiast wygląda tak:
Przy ustawieniu "SET NAMES latin1" funkcja działała tak jak trzeba, co jednak z tego skoro reszta danych pobieranych z bazy krzaczyła się niemiłosiernie, konwersje znaków nie przynosiły rezultatu, jednak nie wpadłem na to by je w sobie zagnieździć. Rozwiązanie, które okazało się (chwilę później) tylko tymczasowym to "convert(CONVERT(CONVERT('ciąg znaków zawierający polskie ogonki' USING latin1) USING binary) using utf8);" (źródło #2). Chwilę później bowiem natknąłem się na inną stronę (źródło #3), która jako rozwiązanie podobnych problemów radziła by typem zmiennej, która przechowuje polskie znaki (oraz znaki charakterystyczne dla innych języków) był BLOB (binarny) nie zaś CHAR (z tego typu korzystałem wcześniej). W ten sposób problem został rozwiązany, by nie być gołosłownym, oto przykład prostej funkcji:

  1. DELIMITER //
  2.  
  3. DROP FUNCTION IF EXISTS testMeNow;
  4. CREATE FUNCTION testMeNow ()
  5. RETURNS char(20)
  6. BEGIN DECLARE result BLOB(100);
  7. SET result = 'ąęćłśóżźŻÓŁŹŚĄĘ';
  8. RETURN result;
  9. END
  10.  
  11. //
  12.  
  13. DELIMITER ;


Dzięki erix za zainteresowanie.

Mam nadzieję, że rozwiązanie przyda się komuś w przyszłości, bo w Internecie niewiele na ten temat znalazłem (a zwłaszcza w języku polskim).
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.