简体   繁体   中英

What param type to use when I need to pass a list of IDs to be used for IN operator for a Stored Procedure?

I want to pass a list of ids '' or '1,2,3,4,5,6,7' to a Stored Procedure, and later in there to use in the following way: col IN (_PARAM)

I already looked into SET but that can have a maximum of 64 elements.

What param type I have to use when I define the Stored Procedure? If I have more options what is the advantage of one compared to the other?

为什么不使用VARCHAR将它们作为字符串传递。

Not a very elegant solution but your choices are limited until MySQL matures.

Split the comma separated ids into tokens and insert into an in-memory table. Join the in-memory table to whatever other tables you require...

Full script here : 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');

Actually after a while of searching I found two solutions:

1 way

use of PREPARE statement and that way I can CONCAT the '1','2','3' formatted VARCHAR param in the query itself.

So it would be something like

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

2nd way

Is to pass a joined list like '1,2,3' as VARCHAR param, and use the FIND_IN_SET call to look up the values

in this way the query will look like

... FIND_IN_SET(col,_PARAM)> 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM