SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 31.01.2009 04:42:20

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 848

Идея о том, как использовать результат выполнения PREPARE STATEMENT

Бывают ситуации, в которых хочется использовать PREPARE STATEMENT (например, когда имя столбца или таблицы удобно получить из переменной). В таких случаях очень неудобно то обстоятельство, что потом результат невозможно никак обработать.
Мне тут в голову идея, что выйти из такой ситуации можно, записывая результат выполнения PREPARE во временную таблицу, с которой уже можно потом нормально работать, повесив курсор и т.п.:

DELIMITER $$

CREATE PROCEDURE p (col1 TEXT, col2 TEXT, tablename TEXT)
BEGIN
    DECLARE a, b INT;
    DECLARE exit_flag INT DEFAULT 0;
    DECLARE c CURSOR FOR SELECT * FROM tmp LIMIT 1; -- курсор можно и на несуществующую ещё таблицу
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET exit_flag = 1;

    SET @q = CONCAT('CREATE TEMPORARY TABLE tmp SELECT ', col1, ',', col2, ' FROM ', tablename);
    -- зараза, не разрешает присвоить обычной переменной, т.е. SET q = ...
    -- надо обязательно глобальную
    PREPARE s FROM @q;
    EXECUTE s; -- тут и создаётся временная таблица
   
    -- с ней, вроде бы, можно после этого нормально работать:
    OPEN c;
        fetch_loop: LOOP
        FETCH c INTO a, b;
        IF exit_flag = 1 THEN LEAVE fetch_loop; END IF;
        SELECT a, b;
    END LOOP;
    CLOSE c;
   
    -- и т.д.
   
    DROP TEMPORARY TABLE tmp;
END $$

Даже работает:

mysql> CREATE TABLE t (x INT, y INT);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO t (x, y) VALUES (1, 100), (2, 200);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> CALL p('x', 'y', 't');
+------+------+
| a    | b    |
+------+------+
|    1 |  100 |
+------+------+
1 row in set (0.00 sec)

Код, конечно, полон извращений. Но иногда другого выхода нет.

Что скажете?

Неактивен

 

#2 31.01.2009 16:15:04

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

Re: Идея о том, как использовать результат выполнения PREPARE STATEMENT

Плохо, что только две колонки и их число фиксировано.

Неактивен

 

#3 31.01.2009 19:37:41

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 848

Re: Идея о том, как использовать результат выполнения PREPARE STATEMENT

Ну, основная идея тут - именно поймать результат PREPARE.
Плохо, конечно, что нужно наперёд знать количество колонок (точнее, можно и не знать, но тогда не получится потом читать курсором, т.к. действительно неизвестно, сколько переменных).
С другой стороны, часто количество колонок известно. Я, например, сейчас столкнулся с задачей, в которой известно, сколько колонок, неизвестно только название таблицы.

Неактивен

 

Board footer

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