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

Есть следующая задачка - нужно в конструкции 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
возврат таблицы из хранимой процедуры для использования в in()
    #39150927
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bannndiПока я понимаю так, что смогу использовать возвращаемую из хр. проц. таблицу в конструкции in() .Нет, в MySQL так нельзя.


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


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


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


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


Akina, приведите пример, пожалуйста. Я использую PDO и подготовленные запросы, но пока не сталкивался с тем, чтобы хоть както можно было строку вида "111,222,333" превратить в аргумент для in(111,222,333)
...
Рейтинг: 0 / 0
возврат таблицы из хранимой процедуры для использования в in()
    #39151301
bannndi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Предположим, в хранимой процедуре я всеже буду удалять и создавать временную таблицу, в которую буду инсертить 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
возврат таблицы из хранимой процедуры для использования в in()
    #39151413
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
возврат таблицы из хранимой процедуры для использования в in()
    #39151505
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bannndiПредположим, в хранимой процедуре я всеже буду удалять и создавать временную таблицу, в которую буду инсертить 111, 222, 333. Тогда мне непонятно, как или где в селекте вызывать данную процедуру так, чтобы в in(я мог написать так: select part from temp_table).

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

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

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

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



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

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


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

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

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


miksoft, правильно! )
...
Рейтинг: 0 / 0
возврат таблицы из хранимой процедуры для использования в in()
    #39151624
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bannndi , ох, не использовал бы ты этот костыль в качестве решения... всё-таки парсинг в temporary table предпочтительнее.
...
Рейтинг: 0 / 0
возврат таблицы из хранимой процедуры для использования в in()
    #39151756
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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
возврат таблицы из хранимой процедуры для использования в in()
    #39151771
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bannndiвадярезультат из хранимки можно вернуть в виде строки через входной параметр с атрибутом in/out. дальше использовать в операторе in


вадя, наверное, только непонятно как это можно использовать.
в prepared statement, пример уже привели
...
Рейтинг: 0 / 0
возврат таблицы из хранимой процедуры для использования в in()
    #39153773
bannndi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
возврат таблицы из хранимой процедуры для использования в in()
    #39153861
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bannndi,

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

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

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

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

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

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

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
возврат таблицы из хранимой процедуры для использования в in()
    #39154221
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bannndi,


вот решение:

8434456
...
Рейтинг: 0 / 0
возврат таблицы из хранимой процедуры для использования в in()
    #39155931
bannndi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivОтвечаю на всякий случай прямо на поставленные вопросы , может будет полезно.


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


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