将IN()子句与存储过程一起使用

时间:2011-04-11 10:26:11

标签: mysql

我有一个存储过程接受下面一个参数:

getData (
  param varchar(500)
)
BEGIN
  SELECT *
  FROM category
  WHERE ID in ( param );
END

鉴于param是“1,2,3”,如何将其作为1,2,3而不是varchar的“”来执行与ID IN(1,2,2)相同的查询而不是ID in ("1,2,3")

2 个答案:

答案 0 :(得分:2)

我非常害怕,因为mysql procs目前不支持数组类型参数:

示例电话:

mysql> call foo('2,4,6');
+---------+----------+
| user_id | username |
+---------+----------+
|       2 | b        |
|       4 | d        |
|       6 | f        |
+---------+----------+
3 rows in set (0.00 sec)

完整脚本:

drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varchar(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');

答案 1 :(得分:-1)

鉴于param会像'1,2,3'那样你可以创建预备语句然后执行它

SET query = CONCAT('SELECT * FROM category WHERE ID in (',param,')');
PREPARE stmt FROM query;
EXECUTE stmt;