SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 17.05.2008 11:32:56

radius
Участник
Зарегистрирован: 17.05.2008
Сообщений: 4

CONCAT в хранимых процедурах (вопрос про кодировки)

Здравствуйте!
Я отчаялся самостоятельно решить проблему, посему прошу хоть чей-либо помощи по решению сложившейся особенности.
Есть:
собственно,  имеется следующее - MySQL 5.0.16, WS2K3 R2 и хранимка на мускуле (работающем под обозначенным сервером):

Код:

CREATE FUNCTION `test`(vUid int, delim char(1)) RETURNS varchar(512)
BEGIN
  declare vF(16);
  declare vS varchar(32);
  declare vT varchar(32);


  select t.f, t.s, t.t
  into vF, vS, vT
  from test t;

  return concat(vF, vS, vT);
END $$

DELIMITER ;

ПРОБЛЕМА:

делаем так:

Код:

insert into test values ('first', 'second', 'third');
select test(0, ',');

получаем:
'first', 'second', 'third'

далее делаем вот так:

Код:

delete from test

и затем, собственно "проблемные данные":

Код:

insert into test values ('первое', 'второе', 'третье');
select test(0, ',');

и после этого всё... то есть, когда в таблице находится строки кириллицы, ф-ция CONCAT позвращает пустое значение...

Однако, если сделать:

Код:

SELECT CONCAT(t.f, t.s, t.t)
FROM test t;

то получаем, что и ожидалось:
'первоевтороетретье' (запятые и прочее убрано для простоты)

то есть, CONCAT отрабатывает из клиента корректно, когда же внутри хранимой процедуры(вызванной из того же самого клиента - то есть, значение character_set_connection и прочие не менялись), возвращается просто пустая строка.




ИНФА:
1. переменные
character_set_client utf8
character_set_connection utf8
character_set_database cp1251
character_set_results utf8
character_set_server utf8
character_set_system utf8
collation_connection utf8_general_ci
collation_database cp1251_general_ci
collation_server utf8_general_ci

изменения character_set_connection на cp1251 (именно в этой кодировке находятся все таблицы, столбцы и база) ничего не дали.

2. база

Код:

CREATE DATABASE `myTest` /*!40100 DEFAULT CHARACTER SET cp1251 */;

3. таблица test

Код:

DROP TABLE IF EXISTS "myTest"."test";
CREATE TABLE  `myTest`.`test` (
  `f` varchar(32) default NULL,
  `s` varchar(32) default NULL,
  `t` varchar(32) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=cp1251;

Суть вопроса:
при помощи каких инструкций/действий можно добиться ожидаемого поведения ф-ции CONCAT, то есть что бы

Код:

insert into test values ('первое', 'второе', 'третье');
select test(0, ',');

возвращало 'первое', 'второе', 'третье', а не пустую строку.

большое спасибо.

Отредактированно radius (17.05.2008 12:02:56)

Неактивен

 

#2 17.05.2008 12:16:25

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: CONCAT в хранимых процедурах (вопрос про кодировки)

Добрый день!

У меня получилось выполнить действия, которые Вы описываете, но ошибки не возникло. Делаю в консоли mysql в linux.

Код:

mysql> CREATE DATABASE `myTest` /*!40100 DEFAULT CHARACTER SET cp1251 */;
Query OK, 1 row affected (0.36 sec)

mysql> DROP TABLE IF EXISTS "myTest"."test";
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"myTest"."test"' at line 1
mysql> CREATE TABLE  `myTest`.`test` (
    ->  `f` varchar(32) default NULL,
    ->  `s` varchar(32) default NULL,
    ->  `t` varchar(32) default NULL
    -> ) ENGINE=InnoDB DEFAULT CHARSET=cp1251;
Query OK, 0 rows affected (0.01 sec)

mysql> set names koi8r;
Query OK, 0 rows affected (0.00 sec)

mysql> use myTest;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> insert into test values ('первое', 'второе', 'третье');
Query OK, 1 row affected (0.00 sec)

mysql> DELIMITER $$
mysql> CREATE FUNCTION `test`(vUid int, delim char(1)) RETURNS varchar(512) BEGIN  declare vF varchar(16);  declare vS varchar(32);  declare vT varchar(32);  select t.f, t.s, t.t  into vF, vS, vT  from test t;  return concat(vF, vS, vT); END$$

mysql> select test(0, ',')$$
+--------------------+
| test(0, ',')       |
+--------------------+
| первоевтороетретье | 
+--------------------+
1 row in set (0.00 sec)

mysql> \s
--------------
mysql  Ver 14.12 Distrib 5.0.22, for redhat-linux-gnu (i686) using readline 5.0

Connection id:          2
Current database:       myTest
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ''
Using delimiter:        $$
Server version:         5.0.22-log
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    cp1251
Db     characterset:    cp1251
Client characterset:    koi8r
Conn.  characterset:    koi8r
UNIX socket:            /var/lib/mysql/mysql.sock
Uptime:                 18 min 13 sec

Threads: 1  Questions: 157  Slow queries: 0  Opens: 75  Flush tables: 1  Open tables: 64  Queries per second avg: 0.144

В каком клиенте Вы работаете?

Неактивен

 

#3 17.05.2008 12:38:54

radius
Участник
Зарегистрирован: 17.05.2008
Сообщений: 4

Re: CONCAT в хранимых процедурах (вопрос про кодировки)

спасибо за Ваш ответ!

версия клиента явно не указывалось, так как я использовал несколько клиентских прилодений, и счёл, что клиент здесь не причём.
конкретно, используемые клиенты:
1. скрипт на PHP через PDO драйвер
(php_pdo_mysql.dll. V5.2.6.6.
php-5.2.6-Win32
)

2. нейтив-клиент mysql.exe

3. MySQL Query Browser, V1.2.12

4. SQL Developer c драйвером mysql-connector-java-5.0.8-bin.jar

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

ТАК ЖЕ, вне зависимости от клиента, CONCAT внутри хранимки не отрабатывает, когда же, с другой стороны, из-под того-же самого клиента (без изменения каких-либо переменных, отвечающих за кодировку) CONCAT вне хранимой процедуры отрабатывает как и должно.
~~~
разумеется, пересоздание хранимки и таблицы, вклучая пересоздание сабой БД так же ни к чему не привели. Однако Ваш лог однозначно показывает, что проблема здесь именно с кодировками, но "вкакомименноместе" я уже отчаялся найти самостоятельно.

Отредактированно radius (17.05.2008 12:42:44)

Неактивен

 

#4 17.05.2008 12:46:33

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: CONCAT в хранимых процедурах (вопрос про кодировки)

Так как у меня все работает, как показал Вам, должен задать еще вопросы
1. Работает ли без CONCAT? Просто возврат первого значения?
2. Сам скрипт на PHP написан на UTF8?
3. Есть ли в скрипте PHP после подключения mysql_query("SET NAMES UTF8");
4. Какая версия сервера?
5. Меняет ли что-то явное задание кодировок в функции

CREATE FUNCTION `test`(vUid int, delim char(1)) RETURNS varchar(512) CHARSET UTF8 BEGIN  declare vF varchar(16) CHARSET UTF8;  declare vS varchar(32) CHARSET UTF8;  declare vT varchar(32);  select t.f, t.s, t.t  into vF, vS, vT  from test t;  return concat(vF, vS, vT); END$$

Неактивен

 

#5 17.05.2008 13:01:38

radius
Участник
Зарегистрирован: 17.05.2008
Сообщений: 4

Re: CONCAT в хранимых процедурах (вопрос про кодировки)

rgbeast написал:

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

да, select getUserInfo(0, ',');
возвращает, например "Текстовая_строка", в корректной кодировке (из всех вышеперечисленных клиенов)

rgbeast написал:

2. Сам скрипт на PHP написан на UTF8?

cp1251

rgbeast написал:

3. Есть ли в скрипте PHP после подключения mysql_query("SET NAMES UTF8");
[/rgbeast]
нет, есть
set character set cp1251
SET NAMES cp1251

rgbeast написал:

4. Какая версия сервера?

5.0.16

rgbeast написал:

5. Меняет ли что-то явное задание кодировок в функции

CREATE FUNCTION `test`(vUid int, delim char(1)) RETURNS varchar(512) CHARSET UTF8 BEGIN  declare vF varchar(16) CHARSET UTF8;  declare vS varchar(32) CHARSET UTF8;  declare vT varchar(32);  select t.f, t.s, t.t  into vF, vS, vT  from test t;  return concat(vF, vS, vT); END$$

нет, никаких изменений.
впрочем как и игра с кодовыми страницами (CHARSET UTF8, CHARSET cp1251)

Отредактированно radius (17.05.2008 13:11:49)

Неактивен

 

#6 17.05.2008 13:15:27

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: CONCAT в хранимых процедурах (вопрос про кодировки)

Возможно это бага сервера, попробуйте обновить MySQL до последней версии

Неактивен

 

#7 17.05.2008 14:22:21

radius
Участник
Зарегистрирован: 17.05.2008
Сообщений: 4

Re: CONCAT в хранимых процедурах (вопрос про кодировки)

сорри за долгий ответ, и СПАСИБО!
проблема заключалась в том, что я сам прямо сейчас на работе проапдейдить сервак не мог, так как работаю в терминалке, а админ - даун, на сотрудничество между сотрудниками не идёт, а просто  тупо и вульгарно посылает wink

рекомендации разработчика MySQL произвели впечатление на нач. отдела, и мы обновили сервер до последней версии 5.0.51b - ошибка исчезла...

Большое спосибо за принятие участия в дискусии

p.s. админ бежит за пивом wink

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson