Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: REGEXP, CONVERT, COLLATE
Forum PHP.pl > Forum > Bazy danych > MySQL
code_berzerker
Mam takie zapytanie:
  1. SELECT
  2. *
  3. FROM article a,
  4. structure s
  5. WHERE s.id = a.id_structure AND a.active = 1 AND LCASE(CONCAT_WS('', date_time, ' ', title, ' ', lead, ' ', content, ' ', author, ' ', source))
  6. REGEXP CONVERT(_utf8 'słowa kluczowe wyszukiwania' USING latin2) COLLATE latin2_general_ci


Używam go do wstępnej selekcji rekordów do przetworzenia przez mechanizm wyszukiwania w php.
wersja MySQL: 5.0.22
wersje PHP: 4.3.7 oraz 4.4.2
sposób wywołania zapytania: adodb oraz przy pomocy funkcji mysql_*
Zapytanie w każdej kombinacji powyższych wersji zwraca następujący błąd:
1139: Got error 'repetition-operator operand invalid' from regexp

Dziwi mnie tylko fakt, ze takie samo zapytanie wklejone do phpMyAdmina (używającego tej samej wersji php co moje skrypty) działa bez problemu.

Dodam że zapytanie nie zwracało błędów gdy nie używałem CONVERT ani COLLATE, ale wtedy nie wszystkie wyniki się znajdowały (dla bazy/tabel/pól ustawiona jest metoda porównywania znaków: latin2_general_ci).

Czy ktoś spotkał się z tym problemem i wie jak go rozwiązać?

pozdrawiam

EDIT1:
Naprawdę nikt nic o tym nie wie? Może ktos zna w takim razie inne forum na którym mógłbym się zapytać ...
mysz
Podaj 'CREATE TABLE' i kilka przykładowych INSERTów, ponieważ moje ograniczone testy nie wykazały żadnych problemów podobnych do Twoich.
code_berzerker
W/g moich testów problem nie ma nic wspólnego ze strukturą tabel (z komunikatu parsera regexp przekazanego przez mysql też to wynika). Wystąpi również przy braku złączenia. Zapytanie wywala się kiedy wyrażenie 'słowa kluczowe wyszukiwania' zawiera polskie litery (w szczególności dla "ł" - pewnie też dla innych które nie są wspólne dla latin1 i latin2).
mysz
Ale człowiek jest leniwy, co widzisz na swoim przykładzie: nie chce mi się samemu tworzyć jakichś tabel i zapełniać przykładowymi danymi, a jak napisałem, u mnie podstawowa wersja działa. Tak samo jak Tobie nie chce się podać przykładu. U mnie działa, u Ciebie nie, więc to Twój problem, skoro nie planujesz się wysilić i jednak mi, czy komukolwiek innemu, nieco ułatwić.
code_berzerker
Lenistwo to nadinterpretacja, poprostu przyjąłem, że skoro problem nie ma związku z danymi a jedynie z tym co się wpisze do regexpa, to zapytanie można wykonać na dowolnej tabeli (jednej, bo złączenie tez nie wpływa na błąd). Przyjąłem po cichu (może zbyt pochopnie), że każdy ma dostęp do jakiejś tabeli wypełnionej tekstami po polsku. Oto dump z tabeli

  1. --
  2. -- Struktura tabeli dla `article`
  3. --
  4.  
  5. CREATE TABLE `article` (
  6. `id` int(11) NOT NULL AUTO_INCREMENT,
  7. `id_structure` int(11) NOT NULL,
  8. `id_gallery` int(11) NOT NULL,
  9. `id_lang` varchar(4) NOT NULL DEFAULT 'pl',
  10. `title` varchar(255) DEFAULT NULL,
  11. `lead` text,
  12. `lead_head_lines` text NOT NULL,
  13. `content` text,
  14. `photo` varchar(255) DEFAULT NULL,
  15. `source` varchar(255) DEFAULT NULL,
  16. `author` varchar(255) DEFAULT NULL,
  17. `date_publication` date DEFAULT NULL,
  18. `date_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  19. `type` enum('news','article','advice','new') DEFAULT NULL,
  20. `main_pos` tinyint(1) NOT NULL DEFAULT '0',
  21. `status` enum('edit','pending','sent') NOT NULL DEFAULT 'edit',
  22. `active` tinyint(1) DEFAULT NULL,
  23. PRIMARY KEY (`id`),
  24. KEY `id_lang` (`id_lang`),
  25. KEY `id_gallery` (`id_gallery`),
  26. KEY `active` (`active`),
  27. KEY `date_time` (`date_time`),
  28. KEY `type` (`type`),
  29. KEY `main_pos` (`main_pos`)
  30. ) ENGINE=MyISAM DEFAULT CHARSET=latin2;
  31.  
  32.  
  33. INSERT INTO `article` (`id`, `id_structure`, `id_gallery`, `id_lang`, `title`, `lead`, `lead_head_lines`, `content`, `photo`, `source`, `author`, `date_publication`, `date_time`, `type`, `main_pos`, `status`, `active`) VALUES (2, 56, 0, 'pl', 'Łazienka z problemem', 'Urządzanie małej łazienki przypomina układanie puzzli - trzeba idealnie dopasować wszystkie elementy. Dlatego najpierw warto zadbać o dobry projekt, a później kupować wyposażenie.', 'Urządzanie małej łazienki przypomina układanie puzzli - trzeba idealnie dopasować wszystkie elementy. Dlatego najpierw warto zadbać', '<p align="justify"><a href="pliki/test/test_nhlphoto.jpg"><img hspace="5" src="pliki/artykuly/lazienka_problem_d.jpg" align="right" vspace="5" border="0" /></a>Szukamy miejsca na niezbędne sprzęty - komentuje arch. Katarzyna Jekiełek. Urządzanie małej łazienki przypomina układanie puzzli - trzeba idealnie dopasować wszystkie elementy. Dlatego najpierw warto zadbać o dobry projekt, a później kupować wyposażenie. Jeśli standardowe urządzenia się nie mieszczą, zastąpmy je mniejszymi (tzw. kompaktowymi) albo narożnymi, które zajmą miejsca zwykle niewykorzystane. Dobrym pomysłem jest też zrezygnowanie z wanny na korzyść kabiny prysznicowej - wtedy w łazience może się też zmieścić bidet. Wykańczając wnętrze, użyjmy jasnych kolorów i dużych luster, które optycznie je powiększą. Aby wygodnie korzystać z urządzeń w łazience, należy przed każdym z nich pozostawić określoną wolną przestrzeń: * przed umywalką 70 x 70 cm * przed sedesem 80 x 80 cm * przed bidetem 100 x 70 cm * przed prysznicem 80 x 90 cm * przed wanną 100 x 100 cm.</p><p align="justify"><strong>Wnętrze 1 - projekt Maciej Twaróg.</strong> </p><p align="justify">Łazienka nie dość, że jest mała (ok. 4 m kw.), to jeszcze ma dwoje drzwi - jedne do przedpokoju, drugie, suwane - do sypialni gospodarzy. Ograniczają one możliwość wykorzystania całej powierzchni ścian, w związku z czym w pomieszczeniu nie zmieścił się bidet. Przy jednej z dłuższych ścian zamontowano wygodną wannę. Na prostopadłej do niej, między drzwiami, znalazło się miejsce na kompaktowy podwieszany sedes. Kolejną ścianę zajmuje umywalka, obok której zmieściła się również wąska, ale dość głęboka szafka zbudowana z płyt gipsowo-kartonowych.</p><p align="justify"><strong>Wnętrze 2 - projekt: Joanna Otto.</strong> </p><p align="justify">Mikroskopijne pomieszczenie (niecałe 3 m kw.) pierwotnie było przeznaczone na toaletę. Właściciele postanowili jednak urządzić tu drugą łazienkę, powiększając ją o część znajdującej się obok garderoby. W uzyskanej tym sposobem wnęce powstała wygodna kabina prysznicowa zamykana szklanymi drzwiami. Przy niej z jednej strony usytuowano kompaktowy sedes, natomiast z drugiej - sporą umywalkę zamontowaną na stelażu z półką. Zostało też nieco miejsca na szafkę. Jest płytka, dzięki czemu nie przeszkadza.</p><p align="justify">Tekst: Elżbieta Błasikiewicz Stylizacja: Dorota Karpińska, Anna Kępińska <br />Zdjęcie: Sławomir Frąckowiak<br />Źródło: CZTERY KĄTY </p>', 'artykuly/lazienka_problem_m.jpg', NULL, NULL, NULL, '2006-10-25 14:31:47', 'article', 3, 'edit', 1);


Uproszczone zapytanie sprawiające problem:

  1. SELECT
  2. *
  3. FROM article a
  4. WHERE a.active = 1 AND LCASE(CONCAT_WS('', date_time, ' ', title, ' ', lead, ' ', content, ' ', author, ' ', source))
  5. REGEXP CONVERT(_utf8 'łazienka' USING latin2) COLLATE latin2_general_ci


Przypomnę że SELECT działa bez problemu z phpMyAdmina, natomiast wywala sie ze wspomnianym błędem przy użyciu wewnątrz skryptu PHP.

Pozdrawiam

PS Zastanawiam się co PMA takiego robi, że nie omija problem.
mysz
No to widzę pewien problem: mam na localhoście tylko PHP5, i tutaj na kilka sposobów działa wporzo. Mój przykładowy skrypt:
  1. <?php
  2.  
  3. $db = new PDO('mysql:host=localhost;dbname=test', 'mysz', 'passwd');
  4. $query = "SELECT
  5. *
  6. FROM article a
  7. WHERE a.active = 1 AND LCASE(CONCAT_WS(' ', date_time, title, lead, content, author, source))
  8. REGEXP CONVERT(_utf8 'łazienka' USING latin2) COLLATE latin2_general_ci ";
  9. $stmt = $db->query($query);
  10. echo '<pre>'.str_replace(array('&','<', '>'), array('&', '<', '>'), print_r($stmt->fetchAll(),1)).'</pre>';
  11.  
  12. $stmt = $db->prepare($query);
  13. $stmt->execute();
  14. echo '<pre>'.str_replace(array('&','<', '>'), array('&', '<', '>'), print_r($stmt->fetchAll(),1)).'</pre>';
  15.  
  16. $db = mysql_connect('localhost', 'mysz', 'ttt');
  17. $result = mysql_query ($query);
  18. $row = mysql_fetch_assoc($result);
  19.  
  20. echo '<pre>'.str_replace(array('&','<', '>'), array('&', '<', '>'), print_r($row,1)).'</pre>';
  21.  
  22. ?>


Żadnych problemów. Wersje softu na jakich chwilowo mogłem przetestować:
Kod
% php -v
PHP 5.2.1 (cli) (built: Feb 20 2007 19:10:04)
% mysql -umysz -ppasswd
Welcome to the MySQL monitor.  Commands end with; or \g.
Your MySQL connection id is 63
Server version: 5.0.38-Ubuntu_0ubuntu1-log Ubuntu 7.04 distribution
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.