2011-04-11 52 views
0

子句我有以下一個參數相同的接受存儲過程:使用IN()與存儲過程

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

鑑於參數​​是「1,2,3」我怎樣才能使它作爲1,2, 3用varchar的「」來執行與查詢ID IN(1,2,2)相同的查詢而不是ID in ("1,2,3")

回答

2

非常難看cludge恐怕像MySQL存儲過程目前不支持數組類型PARAMS:

調用示例:

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,2,3'一樣,你可以創建準備語句然後執行它

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

這是製作中的SQL注入漏洞。 – 2012-01-27 00:52:23

+0

事件如果存在SQL注入的可能性,嘗試在存儲過程中進行防禦性編程(或與數據庫或其數據無關的事情)可能會導致無法維護的混亂。我說這取決於程序員是否可以傳遞有效參數或避免存儲過程。 – 2012-01-30 23:34:58

+0

問題不在於存儲過程。它正在評估部分由用戶輸入生成的代碼。這在* any語言中是一個糟糕的主意,而不僅僅是SQL。正如上面的f00所展示的那樣,這個問題可以通過使用SQL來解決,而不會像引導代碼那樣引入漏洞。 – 2012-01-30 23:50:07