SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 25.04.2010 21:45:20

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

INSERT INTO EXECUTE

Ребята, подскажите в MySQL возможно использование конструкции INSERT INTO EXECUTE?

DROP TEMPORARY TABLE IF EXISTS qqq;
CREATE TEMPORARY TABLE qqq (
  `id` INT, INDEX USING BTREE (`id`)
) ENGINE=MEMORY;
SET @request = "SELECT * FROM some_table";
PREPARE r FROM @request;
INSERT INTO qqq EXECUTE r;

MySQL выдает ошибку синтаксиса для приведенной выше конструкции.
Если такой возможности нет, то можно ли как-нибудь обойти ситуацию?

Отредактированно FiMko (25.04.2010 21:55:13)

Неактивен

 

#2 25.04.2010 22:14:08

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

Re: INSERT INTO EXECUTE

Такой возможности нет. Можно обойти:

SET @request = "INSERT INTO qqq SELECT * FROM some_table";
PREPARE r FROM @request;
EXECUTE r;

Неактивен

 

#3 25.04.2010 22:17:40

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: INSERT INTO EXECUTE

rgbeast написал:

Такой возможности нет. Можно обойти:

SET @request = "INSERT INTO qqq SELECT * FROM some_table";
PREPARE r FROM @request;
EXECUTE r;

У меня именно такой вариант, но всё это в хранимке, которую, известно, вызвать из другого select нельзя sad
Вот и непонятно что в итоге с EXECUTE можно сделать...
Да и сам EXECUTE, похоже, использовать внутри SELECT не получится (ERROR 1146 (42S02): Table 'execute' doesn't exist). Получается EXECUTE "вещь в себе", результаты его никому передать не получится?

Отредактированно FiMko (25.04.2010 22:21:08)

Неактивен

 

#4 25.04.2010 22:21:00

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

Re: INSERT INTO EXECUTE

Ничего не понял. Поясните, что у Вас конкретно и как работает и что ожидается.

Неактивен

 

#5 25.04.2010 22:34:04

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: INSERT INTO EXECUTE

rgbeast написал:

Ничего не понял. Поясните что у Вас конкретно и как работает и что ожидается.

1. Есть хранимая процедура (proc()), которая создает запрос (PREPARE r FROM "select * from some_table";) и выполняет (EXECUTE r) его.

2. Есть запрос SELECT, который, предполагалось, должен получать результаты работы упомянутый выше процедуры:
а) Вызвать хранимую процедуру в запросе SELECT через call proc() невозможно (об этом vasya мне заметил в теме Вызов хранимой процедуры из другой хранимой процедуры).
б) Выполнить EXECUTE r непосредственно в запросе SELECT также не выходит - сообщение об ошибке MySQL "ERROR 1146 (42S02): Table 'execute' doesn't exist".
в) поместить результаты работы EXECUTE r во временную таблицу также невозможно (вы указали об этом).

Вопрос: как использовать результаты EXECUTE r в других запросах?

Отредактированно FiMko (25.04.2010 22:42:30)

Неактивен

 

#6 25.04.2010 23:12:45

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

Re: INSERT INTO EXECUTE

Почему нельзя поместить во временную таблицу? Сам подготовленный запрос r может содержать в себе INSERT INTO, как я написал выше. Имя временной таблицы может передаваться в процедуру как аргумент.

Неактивен

 

#7 25.04.2010 23:23:45

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: INSERT INTO EXECUTE

rgbeast написал:

Почему нельзя поместить во временную таблицу? Сам подготовленный запрос r может содержать в себе INSERT INTO, как я написал выше. Имя временной таблицы может передаваться в процедуру как аргумент.

Блин, вот я раздо... самое главное ("INSERT INTO qqq") у вас в запросе и не увидел roll Спасибо!
И всё равно как-то не очевидно, по-моему получается: казалось бы чем должен EXECUTE отличаться от SELECT, почему его нельзя использовать непосредственно внутри других SELECT. Документацию MySQL перерыл, но никаких упоминаний об этом не нашел...

Отредактированно FiMko (25.04.2010 23:24:15)

Неактивен

 

#8 26.04.2010 00:04:52

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

Re: INSERT INTO EXECUTE

Я думаю, что нет никакой логической причины не использовать EXECUTE в подзапросах. Просто нереализованная фича, как и многое другое. Может быть трудность связана с тем, что PREPARE уже содержит план исполнения и его придется внедрять в план исполнения большого запроса.

Неактивен

 

#9 10.06.2010 00:49:55

hhyhbpen
Участник
Зарегистрирован: 10.06.2010
Сообщений: 2

Re: INSERT INTO EXECUTE

Здравствуйте, извините что пишу в существующую тему если это плохо, я новый к mysql и форуму, зарегистрировался ради этой темы.

У меня есть prepared statement подобный приведенному в посте #2.
Но осложнение: он создается и используется внутри хранимой процедуры, которая производит очень большую сортировку.
Это создает "мультирезультаты", поэтому процедуру нельзя вызвать call'ом в phpMyAdmin, или даже через клиент mysql (не нашел опции), а только внутри программы-пускателя с client_multi_results в mysql_real_connect (или я что-то не знаю...).
Это было бы наверное не страшно, если бы не большой объем результатов которые будут накапливаться за время исполнения процедуры (и наверно кушать память, много) - и полностью впустую и зря, т.к. они не нужны, суть операции сделана в самой SP.
Как я где-то на другом форуме прочитал, подавить их никак нельзя, но предлагалось использовать select ... into <переменные>. Но мне это не подходит, т.к. это работает только для однострочного результата, а мне нужно выбрать и вставить во временную таблицу несколько строк (внутри prepared statement'а и без генерации мультирезультатов...). Именно поэтому я кстати и вынужден использовать prepared statements - только так можно управлять аргументом limit'а, который у меня там обязательно стоит, и переменный.
Как быть?

Спс.

Неактивен

 

#10 10.06.2010 01:28:54

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: INSERT INTO EXECUTE

Насколько я понимаю, INSERT … SELECT не отдает наружу ResultSet. Как
следствие, ничего плодиться не должно. Можете какой-то пример привести?

Если Вам нужно хранить несколько строк — храните их во временной таб-
лице (а не в переменных). Ну и, если открытый (без INSERT) SELECT только
один, то мультирезультат будет (один лишний будет из-за вызова процедуры),
но ничего страшного в этом нет.

Неактивен

 

#11 10.06.2010 10:35:30

hhyhbpen
Участник
Зарегистрирован: 10.06.2010
Сообщений: 2

Re: INSERT INTO EXECUTE

Спасибо, я заметил что у меня было даже не INSERT … SELECT, а INSERT INTO … (SELECT .....).
Убрал скобки, пересоздал SP, но и с ними был мульти, как я думаю из-за того, что в select'е был еще вложенный select:

PREPARE find FROM "

INSERT INTO tmptbl_found
        SELECT userid FROM
            (

      SELECT userid FROM Soul
      WHERE
        <комплексное условие с несколькими ?>
      ORDER BY
        <выражение с несколькими ?>

            ) AS left_tbl
          LEFT JOIN
            Contact
          ON userid = <одному из 2 userid-ов таблицы Contact>
        WHERE Contact.userid1 IS NULL LIMIT ?     #в смысле "подыскать человеку еще контактов из числа тех
                                                  #кто уже не в них и так чтобы итого прирост был <= limit"
";


Тогда я предположил, что и между select и select можно скобку убрать, вдруг как с insert...select не должно быть мульти. Удивительно, но SP создалась без ошибок (или не удивительно?). Но мульти были.

paulus написал:

мультирезультат будет (один лишний будет из-за вызова процедуры),
но ничего страшного в этом нет.

Проблема в том, что один лишний из-за call, плюс N лишних размером в limit (~5), т.к. statement вызывается через execute N раз (там в самой SP еще стоит курсор), где N - это число записей в Soul, которое ожидается большим. Процедура должна сделать полный цикл по всем пользователям системы и для каждого сделать полный select по всем остальным пользователям. Я подозреваю, это и так страшно долго...если еще и мульти будут память зря кушать.

P.S. по-моему, даже при prepare из пустой строки, есть мульти. Их не ставало только когда я убирал execute.

Отредактированно hhyhbpen (10.06.2010 11:20:06)

Неактивен

 

Board footer

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