Как починить багу No data to FETCH

0 views
Skip to first unread message

I1t...@gmail.com

unread,
May 31, 2006, 11:34:31 AM5/31/06
to ua_mysql
Всем привет!

Пишу хранимку для транслитерации
не-английских букв в английские (для
URL). Под это дело есть специальная
таблица с "буквой До" и "буквой После".

При вызове одиночных данных всё ОК, а
при апдейте таблицы вылазит ошибка No
data to FETCH. Как лечить?

Хранимка выглядит так:

delimiter //;
DROP FUNCTION IF EXISTS translit;\g
CREATE FUNCTION translit(s TEXT) RETURNS TEXT
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE output VARCHAR(500) CHARACTER SET utf8 DEFAULT '';
DECLARE new_s VARCHAR(500) CHARACTER SET utf8 DEFAULT TRIM(CONVERT(s
USING utf8)) ;
DECLARE str_len INT DEFAULT CHAR_LENGTH(new_s);
DECLARE c VARCHAR(1) CHARACTER SET utf8; /* one symbol from @s */
DECLARE c_trans VARCHAR(3) CHARACTER SET utf8; /* @c translated */
DECLARE ok_symbols VARCHAR(255) CHARACTER SET utf8 DEFAULT
LCASE('-01234567890 abcdefghijklmnopqrstuvwxyz'); /* symbols not to
translit */

SET NAMES utf8;
SET collation_connection = 'utf8_general_ci';


WHILE i <=str_len DO /* go through the incoming string */
SET c_trans = '';
SET c = SUBSTR(new_s, i, 1); /* get new symbol */
IF LOCATE(LCASE(CONVERT(c USING utf8)), ok_symbols) = 0 THEN /*not
OK symbol, should be converted*/
SELECT `char_to` INTO c_trans FROM `translit` WHERE
`char_from`=LCASE(CONVERT(c USING utf8)) LIMIT 1; /* translit the
symbol */
IF c_trans IS NOT NULL AND c_trans<>'' THEN /* was successfully
translited */
SET output = CONCAT(output, c_trans); /* else the current
symbol is skipped /*
END IF;
ELSE
SET output = CONCAT(output, c); /* the current symbol is in
OK-list, just copy */
END IF;
SET i = i + 1;
END WHILE;
SET output = REPLACE(output,' ', ' '); /* remove double spaces
twice :] */
SET output = REPLACE(output,' ', ' ');
RETURN output;
END\g

A4

unread,
Jun 6, 2006, 1:06:43 PM6/6/06
to ua_mysql
Врика!

Это баг. Проблема возникает потому, что
когда происходит SELECT ... INTO var , селект
может вернуть пустой рекорд-сет, и это
вызывает ошибку.

Не знаю, пофиксят ли этот баг, а мне
работать надо, поэтому я сделал такой
work around:

1. Определил переменную
DECLARE is_trans_present INT;

2. Перед вот этой строкой:

SELECT `char_to` INTO c_trans FROM `translit` WHERE
`char_from`=LCASE(CONVERT(c USING utf8)) LIMIT 1;

вставил эти пару строк:

SELECT COUNT(`char_to`) INTO is_trans_present FROM `translit`
WHERE `char_from`=LCASE(CONVERT(c USING utf8));
IF is_trans_present > 0 THEN

и перед ELSE закрыл этот добавочный
IF-блок.

Как это работает: COUNT() в любом случае
что-то вернёт, хотя бы и нуль. Если не
нуль, значит, можно выбирать из базы
значение, иначе пропускаем итерацию.

Reply all
Reply to author
Forward
0 new messages