Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / возврат таблицы из хранимой процедуры для использования в in() / 25 сообщений из 26, страница 1 из 2
19.01.2016, 18:02:17
    #39150870
bannndi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
Всем здравствуйте!

Есть следующая задачка - нужно в конструкции in() селекта подзапроса использовать значение поля, представленного в виде перечня неких чисел. А поскольку в in() нужно перечислить через запятую значения или воспользоваться подзапросом, - то мне нужно каким то образом преобразовать значение поля вида ("111,222,333") в in(111, 222, 333) или in(... таблица-последовательность этих чисел ...)



Мой упрощенный запрос

select "ттп".*
from "таблица товаров приходов" "ттп"
where 1
and "ттп"."тип товара" = "запчасть"
and ("ттп".count) <> (
select sum(count)
from "таблица товаров приходов" /* т.е. из этой же таблицы */
where 1
and "код прихода" = "ттп"."код прихода"
and "ттп"."тип товара" <> "запчасть"
and "ттп"."код товара" in(/*сдесь собираюсь использовать значение поля запчасти "ттз"."перечень кодов товаров" таблицы main_table вида ("111,222,333", "222,111", "555", null и т.п.)*/)
)

Т.е., таблица "таблица товаров приходов" хранит товары и запчасти. Смысл запроса - вывести все запчасти, количество которых "count" не равно сумме остальных типов товаров данной таблицы, но в пределах каждого конкретного прихода.


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

Я в них новичок, и пока смог "придумать" только такую:


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
DROP PROCEDURE if exists explode;
DELIMITER //
CREATE PROCEDURE `explode`(IN `mylist` VARCHAR(255))
-- body:
-- RESULT (`part` LONG VARCHAR)
BEGIN


    drop table if exists `xxxx`;
    create table `xxxx` (
        `part` varchar(255),
        KEY `part` (`part`)
    ) engine=myisam collate 'utf8_general_ci';
/* ТАБЛИЦА xxxx удаляется и создается */
/*движок вероятно потом использую memory*/


/* здесь я планировал в цикле разобрать входной параметр mylist, и заполнить врем. таблицу xxxx разбитыми частями*/


/* и вернуть ее чтобы использовать в селекте в in(result) */
SELECT part
FROM xxxx
where 1
;
 
END//
DELIMITER ;

call explode('111,222,333');



Этот код полностью работает.

Пока я понимаю так, что смогу использовать возвращаемую из хр. проц. таблицу в конструкции in() .
Проблема в том, что не получается сделать работающий запрос.
Пытался делать по примеру данной статьи http://citforum.ru/database/sql_any/sql_062.shtml
Но запутался, когда дошло дело до таблицы CURSOR.

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

На данном этапе (с RESULT) я получаю ошибку "Error in query (1064): Syntax error near '(`part` LONG VARCHAR) BEGIN drop table if exists `xxxx`; create t' at line 3", далее по статье продвинуться не могу. Также не нашел что означает конструкция "body:", но ни с ней, ни без нее не работатает без ошибки.

Т.е., хранимая процедура explode на данный момент ошибок не выдает, пока не раскомментирую RESULT ... Пока мыслей больше нет, нужна помощь )
...
Рейтинг: 0 / 0
19.01.2016, 19:18:55
    #39150927
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndiПока я понимаю так, что смогу использовать возвращаемую из хр. проц. таблицу в конструкции in() .Нет, в MySQL так нельзя.


bannndiв операторе RESULT перечислить поля возвращаемой таблицы.в MySQL нет такой конструкции.
...
Рейтинг: 0 / 0
20.01.2016, 10:52:17
    #39151207
bannndi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
miksoftbannndiПока я понимаю так, что смогу использовать возвращаемую из хр. проц. таблицу в конструкции in() .Нет, в MySQL так нельзя.


bannndiв операторе RESULT перечислить поля возвращаемой таблицы.в MySQL нет такой конструкции.


Обескуражен. И придумать совсем ничего нельзя? Учитывая условия задачи, конечно.


Я еще держу про запас план с отдельной таблицей "многие ко многим" для хранения связей конкретных позиций приходов с запчастями, но так хотелось обойтись без нее. Редактироваться это поле не будет, так что было бы удобно.
...
Рейтинг: 0 / 0
20.01.2016, 10:59:27
    #39151217
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndi,
скидывай числа в табличку, будет в сто раз проще.
...
Рейтинг: 0 / 0
20.01.2016, 11:35:37
    #39151256
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
Можно использовать prepared statement.
...
Рейтинг: 0 / 0
20.01.2016, 11:49:42
    #39151278
bannndi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
AkinaМожно использовать prepared statement.


Akina, приведите пример, пожалуйста. Я использую PDO и подготовленные запросы, но пока не сталкивался с тем, чтобы хоть както можно было строку вида "111,222,333" превратить в аргумент для in(111,222,333)
...
Рейтинг: 0 / 0
20.01.2016, 12:17:59
    #39151301
bannndi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
Предположим, в хранимой процедуре я всеже буду удалять и создавать временную таблицу, в которую буду инсертить 111, 222, 333. Тогда мне непонятно, как или где в селекте вызывать данную процедуру так, чтобы в in(я мог написать так: select part from temp_table).

Копия селекта из первого поста
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select "ттп".*
from "таблица товаров приходов" "ттп"
where 1
    and "ттп"."тип товара" = "запчасть"
    and ("ттп".count) <> (
        select sum(count)
        from "таблица товаров приходов" /* т.е. из этой же таблицы  */
        where 1
            and "код прихода" = "ттп"."код прихода"
            and "ттп"."тип товара" <> "запчасть"
            and "ттп"."код товара" in(/*если получится так сделать, то планирую написать здесь select part from temp_table) , где temp_table будет пересоздаваться с помощью хранимой процедуры, в которой будет разбиваться строка "111,222,333" и инсертиться в врем. таблицу temp_table*/)
    )



По моей логике, процедура должна вызываться в самом селекте, чтобы временная таблица пересоздавалась для каждого товара (не запчасти), но где именно можно и нужно ее вызывать - не ясно.
...
Рейтинг: 0 / 0
20.01.2016, 13:43:35
    #39151413
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndiстроку вида "111,222,333" превратить в аргумент для in(111,222,333)
Код: sql
1.
2.
3.
SET @args = '111,222,333';
PREPARE stmt FROM CONCAT('SELECT * FROM `table` WHERE id IN (',@args,')');
EXECUTE stmt;
...
Рейтинг: 0 / 0
20.01.2016, 14:42:43
    #39151505
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndiПредположим, в хранимой процедуре я всеже буду удалять и создавать временную таблицу, в которую буду инсертить 111, 222, 333. Тогда мне непонятно, как или где в селекте вызывать данную процедуру так, чтобы в in(я мог написать так: select part from temp_table).

Тебе не надо удалять и создавать таблицы.
Создай таблицу один раз. В PK добавь SPID или как он там у нас называется.
Идентификатор сеанса.

И набивай для данного сеанса туда данные. Когда не нужны -- удаляй.
Перед тем, как набить, тоже удаляй на всякий случай.
...
Рейтинг: 0 / 0
20.01.2016, 14:52:40
    #39151522
вадя
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
результат из хранимки можно вернуть в виде строки через входной параметр с атрибутом in/out. дальше использовать в операторе in
...
Рейтинг: 0 / 0
20.01.2016, 15:10:06
    #39151535
bannndi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
MasterZivbannndiПредположим, в хранимой процедуре я всеже буду удалять и создавать временную таблицу, в которую буду инсертить 111, 222, 333. Тогда мне непонятно, как или где в селекте вызывать данную процедуру так, чтобы в in(я мог написать так: select part from temp_table).

Тебе не надо удалять и создавать таблицы.
Создай таблицу один раз. В PK добавь SPID или как он там у нас называется.
Идентификатор сеанса.

И набивай для данного сеанса туда данные. Когда не нужны -- удаляй.
Перед тем, как набить, тоже удаляй на всякий случай.



Что такое PK? ) Гугл не подсказал. По поводу SPID тоже сомнения, видимо мои знания MySQL недостаточно глубоки. На уровне сессий пока не особо разбираюсь.

Если не трудно, MasterZiv, то может покажете пример всей последовательности действий, а главное - использование в подзапросе селекта. Заранее благодарен. Может поможете если не мне, то кому то другому интересующемуся.
...
Рейтинг: 0 / 0
20.01.2016, 15:10:54
    #39151537
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndiЧто такое PK? ) Гугл не подсказал.
Primary Key
...
Рейтинг: 0 / 0
20.01.2016, 15:11:21
    #39151539
bannndi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
вадярезультат из хранимки можно вернуть в виде строки через входной параметр с атрибутом in/out. дальше использовать в операторе in


вадя, наверное, только непонятно как это можно использовать.
...
Рейтинг: 0 / 0
20.01.2016, 15:12:05
    #39151542
bannndi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
AkinabannndiЧто такое PK? ) Гугл не подсказал.
Primary Key

Тогда подсказал, а я просто не поверил )
...
Рейтинг: 0 / 0
20.01.2016, 15:21:39
    #39151548
bannndi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
На другом форуме мне подсказали отличное решение, но ради "спортивного интереса", пока ответ не буду сообщать здесь.

Вдруг найдутся и другие решения. )
...
Рейтинг: 0 / 0
20.01.2016, 15:31:02
    #39151561
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndiНа другом форуме мне подсказали отличное решение, но ради "спортивного интереса", пока ответ не буду сообщать здесь.Могу предположить, что подсказали функцию FIND_IN_SET. Если использование индексов не требуется, то да, решение подходящее.
...
Рейтинг: 0 / 0
20.01.2016, 16:01:54
    #39151591
bannndi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
miksoftbannndiНа другом форуме мне подсказали отличное решение, но ради "спортивного интереса", пока ответ не буду сообщать здесь.Могу предположить, что подсказали функцию FIND_IN_SET. Если использование индексов не требуется, то да, решение подходящее.


miksoft, правильно! )
...
Рейтинг: 0 / 0
20.01.2016, 16:29:05
    #39151624
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndi , ох, не использовал бы ты этот костыль в качестве решения... всё-таки парсинг в temporary table предпочтительнее.
...
Рейтинг: 0 / 0
20.01.2016, 18:36:30
    #39151756
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
create table SPARE_PART_LIST
(
   spid int not null,
   spare_part_id int not null,
   constraint PK_SPARE_PART_LIST primary key (spid,spare_part_id)
);

create procedure blabla 
as
begin
 
delete SPARE_PART_LIST
where spid = CONNECTION_ID();

delete SPARE_PART_LIST
where spid not in (select ID from INFORMATION_SCHEMA.PROCESSLIST);

insert into SPARE_PART_LIST ( spid, spare_part_id )
select CONNECTION_ID() as spid, 123456 as spare_part_id;

select *
from "таблица товаров приходов" "ттп"
where "ттп"."тип товара" = "запчасть"
and "ттп".count <> (
select sum(count)
from "таблица товаров приходов" 
where "код прихода" = "ттп"."код прихода"
and "ттп"."тип товара" <> "запчасть"
and "ттп"."код товара" in ( select spare_part_id from SPARE_PART_LIST where spid = CONNECTION_ID() )
);

delete SPARE_PART_LIST
where spid = CONNECTION_ID();

delete SPARE_PART_LIST
where spid not in (select ID from INFORMATION_SCHEMA.PROCESSLIST);

end;
/
...
Рейтинг: 0 / 0
20.01.2016, 18:56:42
    #39151771
вадя
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndiвадярезультат из хранимки можно вернуть в виде строки через входной параметр с атрибутом in/out. дальше использовать в операторе in


вадя, наверное, только непонятно как это можно использовать.
в prepared statement, пример уже привели
...
Рейтинг: 0 / 0
23.01.2016, 22:44:32
    #39153773
bannndi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
MasterZiv
Код: sql
1.
2.
create table SPARE_PART_LIST
...




MasterZiv, спасибо за потраченное время, пример познавательный!


Одно мне непонятно. Каким образом будет вызываться данная процедура множество раз в подзапросе подсчета суммы количеств товаров с этой запчастью? Я ведь пытаюсь одним запросом вернуть весь нужный мне результат. Я не хотел бы выполнять этот селект в цикле с подгот. запросом - это ведь займет гораздо больше времени, чем выполнить 1 запрос. Строк в таблице товаров прихода немало. И для половины из них (которые запчасти) придется заново создавать новую таблицу SPARE_PART_LIST (удаляя старую) в новом запросе для каждой итерации.

Я предполагал, что можно сделать нечто подобное:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select "ттп".*
from "таблица товаров приходов" "ттп"
where 1
and "ттп"."тип товара" = "запчасть"
and ("ттп".count) <> (
select sum(count)
from "таблица товаров приходов" /* т.е. из этой же таблицы */
where 1
and "код прихода" = "ттп"."код прихода"
and "тип товара" <> "запчасть" /* здесь кстати была моя ошибка, нужно было не "ттп"."тип товара" */
and "ттп"."код товара" in(SPARE_PART_LIST = call blabla(список id запчастей через запятую))*/)
)



А именно в подзапросе вызывать in(SPARE_PART_LIST = call blabla(параметры)) для пересоздания новой таблицы для каждого товара (т.е. списка запчастей).

Возможно ли нечто подобное? Или это возможно сделать лишь в цикле скрипта PHP, выясняя для каждого товара его запчасти, вызывать процедуру для пересоздания SPARE_PART_LIST, и возврата части результата для прикрепления к общему результату?
...
Рейтинг: 0 / 0
24.01.2016, 09:17:36
    #39153861
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndi,

янихренанепонял что тебе надо, но
отвечу: все просто.

заполняешь список деталей в одной процедуре

потом делаешь запрос со сколько угодно подзапросами, или даже несколько запросов.
возможно, в другой процедуре.

потом очищаешь список , в третьей процедуре.

расклад по процедурами в принципе произвольный , не жестко.

да и свои понятия о "быстрее/ медленнее" лучше оставь при себе, а еще лучше вообще забудь, все не так.
...
Рейтинг: 0 / 0
24.01.2016, 09:19:26
    #39153862
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndi,
еще потом посмотрю, Может таки врулюсь чего ж тебе надо...
...
Рейтинг: 0 / 0
24.01.2016, 18:57:31
    #39154037
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
Отвечаю на всякий случай прямо на поставленные вопросы , может будет полезно.

bannndi Каким образом будет вызываться данная процедура множество раз в подзапросе подсчета суммы количеств товаров с этой запчастью?


Никаким. Процедура будет вызываться ДО выполнения всех запросов и подзапросов, и ОДИН РАЗ.

bannndi
Я ведь пытаюсь одним запросом вернуть весь нужный мне результат.
...
Есть следующая задачка - нужно в конструкции in() селекта подзапроса использовать значение поля, представленного в виде перечня неких чисел. А поскольку в in() нужно перечислить через запятую значения или воспользоваться подзапросом, - то мне нужно каким то образом преобразовать значение поля вида ("111,222,333") в in(111, 222, 333) или in(... таблица-последовательность этих чисел ...)


Верни одним запросом весь результат, на здоровье.
Это никак не заставляет тебя делать несколько раз "перечень неких чисел".




авторЯ не хотел бы выполнять этот селект в цикле с подгот. запросом - это ведь займет гораздо больше времени, чем выполнить 1 запрос.


Подготовленные запросы в таков (моём) варианте вообще не нужны.

авторСтрок в таблице товаров прихода немало. И для половины из них (которые запчасти) придется заново создавать новую таблицу SPARE_PART_LIST (удаляя старую) в новом запросе для каждой итерации.


Не придётся. Если тебе надо группировать запчасти по каким-то признакам, добавь в PK таблицы со списком запчастей ещё и
поля (поле), обозначающие эти признаки. И одним запросом всё вычисляй, без каких-то циклов.

авторЯ предполагал, что можно сделать нечто подобное:
А именно в подзапросе вызывать in(SPARE_PART_LIST = call blabla(параметры)) для пересоздания новой таблицы для каждого товара (т.е. списка запчастей).

Возможно ли нечто подобное? Или это возможно сделать лишь в цикле скрипта PHP, выясняя для каждого товара его запчасти, вызывать процедуру для пересоздания SPARE_PART_LIST, и возврата части результата для прикрепления к общему результату?

Такое невозможно, но даже если бы было возможно, так делать было бы вредно и неправильно.
А мы же плохому-то не учим...
...
Рейтинг: 0 / 0
25.01.2016, 07:07:25
    #39154221
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
возврат таблицы из хранимой процедуры для использования в in()
bannndi,


вот решение:

8434456
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / возврат таблицы из хранимой процедуры для использования в in() / 25 сообщений из 26, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]