Может быть сделано с использованием хранимой процедуры с одним вызовом, но из-за того, что mysql не поддерживает параметры массива, это немного уродливо, так как мы должны передать через запятую строку user_id; file_id tokens. Единственная альтернатива - многократный вызов хранимой процедуры.
Полный скрипт здесь: http://pastie.org/1722362
mysql> select * from user_files;
+---------+---------+-------------+
| user_id | file_id | file_status |
+---------+---------+-------------+
| 1 | 2 | 0 |
| 3 | 6 | 0 |
+---------+---------+-------------+
2 rows in set (0.00 sec)
call check_user_files('user_id;file_id, user_id;file_id...');
call check_user_files('1;2, 2;4, 3;6, 4;10, 50;50, 1000;1, 1;10001');
mysql> select * from user_files;
+---------+---------+-------------+
| user_id | file_id | file_status |
+---------+---------+-------------+
| 1 | 2 | 0 |
| 1 | 10001 | 0 |
| 2 | 4 | 0 |
| 3 | 6 | 0 |
| 4 | 10 | 0 |
| 50 | 50 | 0 |
| 1000 | 1 | 0 |
+---------+---------+-------------+
7 rows in set (0.00 sec)
Хранимая процедура
drop procedure if exists check_user_files;
delimiter #
create procedure check_user_files
(
in p_users_files_csv varchar(4096)
)
proc_main:begin
declare v_token varchar(255);
declare v_done tinyint unsigned default 0;
declare v_token_idx int unsigned default 1;
declare v_user_id int unsigned default 0;
declare v_file_id int unsigned default 0;
set p_users_files_csv = replace(p_users_files_csv, ' ','');
if p_users_files_csv is null or length(p_users_files_csv) <= 0 then
leave proc_main;
end if;
-- the real ugly bit
-- split the string into user_id/file_id tokens and put into an in-memory table...
create temporary table tmp(
user_id int unsigned not null,
file_id int unsigned not null
)engine = memory;
while not v_done do
set v_token = trim(substring(p_users_files_csv, v_token_idx,
if(locate(',', p_users_files_csv, v_token_idx) > 0,
locate(',', p_users_files_csv, v_token_idx) - v_token_idx, length(p_users_files_csv))));
if length(v_token) > 0 then
set v_token_idx = v_token_idx + length(v_token) + 1;
set v_user_id = mid(v_token, 1, instr(v_token, ';')-1);
set v_file_id = mid(v_token, instr(v_token, ';')+1, length(v_token));
insert into tmp (user_id, file_id) values(v_user_id, v_file_id);
else
set v_done = 1;
end if;
end while;
-- the nice bit - insert the new values
insert into user_files (user_id, file_id, file_status)
select
t.user_id, t.file_id, 0 as file_status
from
tmp t
left outer join user_files uf on t.user_id = uf.user_id and t.file_id = uf.file_id
where
uf.user_id is null and uf.file_id is null;
drop temporary table if exists tmp;
end proc_main #
delimiter ;
Надеюсь, это поможет