代码之家  ›  专栏  ›  技术社区  ›  Pentium10

当我需要传递要在存储过程的IN运算符中使用的id列表时,要使用什么样的参数类型?

  •  0
  • Pentium10  · 技术社区  · 14 年前

    我要将ID“”或“1、2、3、4、5、6、7”的列表传递给存储过程,稍后在其中按以下方式使用: col IN (_PARAM)

    我已经调查过了 SET 但是它最多可以有64个元素。

    如果我有更多的选择,一个比另一个有什么优势?

    3 回复  |  直到 14 年前
        1
  •  0
  •   Yasen Zhelev    14 年前

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

        2
  •  0
  •   Jon Black    14 年前

    不是一个非常优雅的解决方案,但是在MySQL成熟之前,您的选择是有限的。

    将逗号分隔的id拆分为标记并插入内存表中。将内存中的表连接到您需要的任何其他表。。。

    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');
    
        3
  •  0
  •   Pentium10    14 年前

    实际上,经过一段时间的搜索,我找到了两个解决方案:

    单程

    CONCAT '1','2','3' 格式化 VARCHAR 查询本身中的参数。

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

    第二条路

    瓦查尔 FIND_IN_SET 调用以查找值

    ... FIND_IN_SET(col,_PARAM)> 0