Какой тип параметра использовать, когда мне нужно передать список идентификаторов, которые будут использоваться для оператора IN для хранимой процедуры? - PullRequest
0 голосов
/ 02 ноября 2010

Я хочу передать список идентификаторов '' или '1,2,3,4,5,6,7' в хранимую процедуру, а затем использовать ее следующим образом: col IN (_PARAM)

Я уже изучил SET, но в нем может быть не более 64 элементов.

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

Ответы [ 3 ]

0 голосов
/ 02 ноября 2010

Не очень элегантное решение, но ваш выбор ограничен, пока MySQL не станет зрелым.

Разделите запятые идентификаторы в токены и вставьте в таблицу в памяти.Присоедините таблицу в памяти к любым другим таблицам, которые вам нужны ...

Полный сценарий здесь: http://pastie.org/1266830

drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varbinary(32) unique not null
)
engine=innodb;

insert into users (username) values ('a'),('b'),('c'),('d'),('e'),('f'),('g');

drop procedure if exists foo;

delimiter #

create procedure foo
(
in p_id_csv varchar(1024)
)
proc_main:begin

declare v_id varchar(10);
declare v_done tinyint unsigned default 0;
declare v_idx int unsigned default 1;

    if p_id_csv is null or length(p_id_csv) <= 0 then
        leave proc_main;
    end if;

    -- split the string into tokens and put into an in-memory table...

    create temporary table ids(id int unsigned not null)engine = memory;    

    while not v_done do
    set v_id = trim(substring(p_id_csv, v_idx, 
      if(locate(',', p_id_csv, v_idx) > 0, 
                locate(',', p_id_csv, v_idx) - v_idx, length(p_id_csv))));

      if length(v_id) > 0 then
        set v_idx = v_idx + length(v_id) + 1;
                insert into ids values(v_id);
      else
        set v_done = 1;
      end if;
  end while;

    select 
        u.* 
    from
     users u
    inner join ids on ids.id = u.user_id
    order by 
        u.username;

    drop temporary table if exists ids;

end proc_main #

delimiter ;

call foo('2,4,6');
0 голосов
/ 02 ноября 2010

На самом деле через некоторое время поиска я нашел два решения:

1 way

использование оператора PREPARE и таким образом я могу CONCAT the '1','2','3'отформатированный VARCHAR параметр в самом запросе.

Таким образом, это будет что-то вроде

  SET @query= CONCAT('...WHERE col IN(',_PARAM,') ');

2-й способ

Передать объединенныйперечислите как '1,2,3' как VARCHAR param, и используйте вызов FIND_IN_SET для поиска значений

, таким образом, запрос будет выглядеть как

... FIND_IN_SET(col,_PARAM)> 0
0 голосов
/ 02 ноября 2010

Почему вы не используете VARCHAR для передачи их в виде строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...