1

Тема: Помогите написать процедуру пожалуйста!!!

Здравствуйте!!!
Пришел к вам за помощью!
Требуется написать хранимую процедуру, а я никак не пойму как это сделать sad

Ща четко напишу чего надо добиться:

Проблема следущая, делаю систему авторизации / регистрации, есть таблица в которой хранятся юзеры, логин хранится в столбце `user`.

В общем перед тем как добавить данные в таблу я проверяю имеется такой юзер с таким логином в базе или нет. Регистр для меня не должен иметь значения, вот тут я сталкнулся с проблемой.

strtolower (PHP) и Lower (MySQL) приводит символы в нижний регистр только латинские, с кирилицей ничего не выходит, они их просто игнорируют.

Что касается strtolower то я написал функцию которая делает все вручную, а вот процедуру написать не умею, надо сделать процедуру которая будет работать точно так же как и функция в плане логики, ниже предоставляю код сценария:


<?php

function strtolower_my($str) {
   $str = strtolower($str);
   $search = array(
      'Й','Ц','У','К','Е','Н','Г','Ш','Щ','З','Х','Ъ','Ф','Ы','В','А','П','Р','О','Л','Д','Ж','Э','Я','Ч','С','М','И','Т','Ь','Б','Ю','Ё'
   );
   $replace = array(
      'й','ц','у','к','е','н','г','ш','щ','з','х','ъ','ф','ы','в','а','п','р','о','л','д','ж','э','я','ч','с','м','и','т','ь','б','ю','ё'
   );
   $str = str_replace($search, $replace, $str);
   return $str;
}

$user = strtolower_my($_POST['user']);

$sql = "Select `id`, `user` From `users` Where LOWER(`user`) = '" . $user . "'";

// Мне надо чтоб запрос выглядел типа так:
// $sql = "Select `id`, `user` From `users` Where LOWER_MY(`user`) = '" . $user . "'";
// Где LOWER_MY это процедура которая делает тоже что и функция strtolower_my


$query = mysql_query($sql);
$result = mysql_fetch_array($query);

if ($result['id']) {
// Ошибка такой юзер уже есть в БД
} else {
// Процедура регистрации ника
}


?>


Надеюсь на вашу помощь, у меня вся работа на этом встала sad

2

Re: Помогите написать процедуру пожалуйста!!!

Tankoff
В данном случае нет необходимости в процедуре, достаточно правильно выставленной кодировки сравнения у поля `user`.
Предположим, что у нас поле `users`.`user` имеет кодировку сравнения utf8_general_ci, что означает: Юникод регистронезависимый. Таким образом запросы ниже выдадут идентичный результат:
Select COUNT(*) From `users` Where `user` = 'тест';
Select COUNT(*) From `users` Where `user` = 'ТЕСТ';

$sql = 'Select COUNT(*) From `users` Where `user` = "' . $user . '"';
$result = mysql_query($sql);
$row = mysql_fetch_row($result);
mysql_free_result($result);

if ($row[0] > 0) {
// Ошибка такой юзер уже есть в БД
} else {
// Процедура регистрации ника
}

3 (изменено: Tankoff, 2008-09-17 17:13:58)

Re: Помогите написать процедуру пожалуйста!!!

Hanut сказал:

Tankoff
В данном случае нет необходимости в процедуре, достаточно правильно выставленной кодировки сравнения у поля `user`.
Предположим, что у нас поле `users`.`user` имеет кодировку сравнения utf8_general_ci, что означает: Юникод регистронезависимый. Таким образом запросы ниже выдадут идентичный результат:
Select COUNT(*) From `users` Where `user` = 'тест';
Select COUNT(*) From `users` Where `user` = 'ТЕСТ';

$sql = 'Select COUNT(*) From `users` Where `user` = "' . $user . '"';
$result = mysql_query($sql);
$row = mysql_fetch_row($result);
mysql_free_result($result);

if ($row[0] > 0) {
// Ошибка такой юзер уже есть в БД
} else {
// Процедура регистрации ника
}

Спасибо за инфу, это меняет дело, но появилась другая проблема!
У меня поле имеет кодировку cp1251_bin, если я делаю utf8_general_ci, то вся кирилица превращается в иероглифы, если делаю cp1251_general_ci, то канает тока с латинскими а с кирилицей не идет. Как мне поменять кодировку поля чтоб не закосячить данные? Подскажите пожалуйста!!!

4

Re: Помогите написать процедуру пожалуйста!!!

Tankoff
С cp1251_bin на cp1251_general_ci можно безболезненно поменять сравнение у поля. Но обратите внимание, что речь идет именно о поле `user`, а не о всей таблице. Примерный вид запроса:

ALTER TABLE `users` CHANGE `user` `user` TINYTEXT CHARACTER SET cp1251 COLLATE cp1251_general_ci NULL DEFAULT NULL;

5

Re: Помогите написать процедуру пожалуйста!!!

Hanut сказал:

Tankoff
С cp1251_bin на cp1251_general_ci можно безболезненно поменять сравнение у поля. Но обратите внимание, что речь идет именно о поле `user`, а не о всей таблице. Примерный вид запроса:

ALTER TABLE `users` CHANGE `user` `user` TINYTEXT CHARACTER SET cp1251 COLLATE cp1251_general_ci NULL DEFAULT NULL;

Я понял это, я через phpMyAdmin поменял на cp1251_general_ci, но говорю, что к латинице регистронезависимый подход, а к кирилице нет.
Незнаю что делать.

6

Re: Помогите написать процедуру пожалуйста!!!

Tankoff
Посмотрите как запрос с измененным регистром искомого текста работает из phpMyAdmin.
Select COUNT(*) From `users` Where `user` = 'ТЕСТ';

Покажите вывод:
SHOW GLOBAL VARIABLES LIKE 'char%';

7

Re: Помогите написать процедуру пожалуйста!!!

SHOW GLOBAL VARIABLES LIKE 'char%';
Выдал:

Variable_name                             Value
character_set_client                cp1251
character_set_connection    cp1251
character_set_database                cp1251
character_set_filesystem     binary
character_set_results          cp1251
character_set_server          cp1251
character_set_system         utf8
character_sets_dir              /usr/share/mysql/charsets/


А из phpMyAdmin запросы в которых кирилица не работают, в плане того что возращают 0.
Объясняю (возможно в этом и вся моя проблема)

Страницы у меня на сайте в utf-8, а в бд поля все cp1251 и вся кирилица через phpMyAdmin отображается мне как иероглифы типа: Система
Может в этом дело? Данные в Utf8 записывал в поля с кодировкой cp1251?

Ничего не пойму! sad

8

Re: Помогите написать процедуру пожалуйста!!!

Tankoff
Конечно же причина в том, что данные в utf8 лежат в таблицах с кодировкой cp1251. А также кодировка соединения с MySQL у вас cp1251 (character_set_connection    cp1251), по причине чего скрипт не сможет нормально работать.

Что надо сделать:
1) В скрипте сразу после функции mysql_connect необходимо добавить строку:

mysql_query('SET NAMES utf8');

2) Все таблицы в БД пересоздать с кодировкой utf8. Именно пересоздать, а не поменять сравнение в phpMyAdmin.

Если данные в БД критичны и их необходимо сохранить, то потребуется перекодировка. Это сложно и надо разбираться отдельно, поэтому лучше создать таблицы заново.

9 (изменено: Tankoff, 2008-09-19 08:41:44)

Re: Помогите написать процедуру пожалуйста!!!

>> Если данные в БД критичны и их необходимо сохранить, то потребуется перекодировка. Это сложно и надо разбираться отдельно, поэтому лучше создать таблицы заново.

К сожалению у меня целая куча таблиц и большинство из них имеет данные которые ни в коем случае нельзя удалять.
Просто на этой базе уже давно работает проект и ща я его полностью переписываю (программную чатсть), а база остается прежняя.

Я хотел перегнать кодировку следущим образом:

1. Созал таблицу (например `users_copy`) с кодировкой utf8_general_ci и в ней все проля сделал с utf8_general_ci (которым необходимо ставить кодировку конечно).

2. С помощью PHP скрипта забирал данные из таблы `users` имеющую кодировку cp1251 и заливал их в таблицу `users_copy`.
Теоретически данные должны сохраниться нормально, но не тут то было. Некоторые буквы, такие как Ш превращались в крокозябры, а некоторые сохронялись нормально.

Подскажите пожалуйста, какие есть способы перекодировки данных?

Если у меня будет база с кодировкой utf8_general_ci, таблица с кодировкой utf8_general_ci и поле с кодировкой utf8_general_ci то записав в него данные в кодировке utf8 (в частности кирилицу) через phpMyAdmin я буду видеть нормальные буквы в обзоре таблицы или иероглифы?

10

Re: Помогите написать процедуру пожалуйста!!!

Hanut скиньте пожалуйста тот скрипт, про который вы говорите в соседней теме! Попробую перегнать кодировку им, как думаете будет результат?

11

Re: Помогите написать процедуру пожалуйста!!!

Tankoff
Результат будет, но надо чётко понимать что делать, так как там все настройки необходимо выставить вручную.

Этапы перекодировки.
1) Создаем дамп в utf8 (изначально он так и создастся).
2) Открываем дамп в текстовом редакторе и смотрим на то как выглядят крякозябы и какие кодировки в структурах таблиц требуется заменить на utf8/utf8_general_ci или utf8_bin для бинарных данных.

Если будут сомнения - покажите крякозябы и структуры таблиц - постараюсь помочь.
Важно понимать, что в таблицах с кодировкой cp1251 у вас хранился utf8, но в phpMyAdmin он отображался символами из таблицы cp1251, что и вызывает крякозябы.

Правильные данные в phpMyAdmin всегда отображаются корректно.

12

Re: Помогите написать процедуру пожалуйста!!!

Спасибо за скрипт и методику! На досуге буду разбираться! smile Если что опять за помощью приду smile