gpt4 book ai didi

mysql - 如何在 MySQL 或 PHP 中多次执行相同的存储过程?

转载 作者:行者123 更新时间:2023-11-29 03:48:42 24 4
gpt4 key购买 nike

在我的previous question .我有解决方案来检查在插入数据之前重复了哪些数据。这是检查数据的MySQL存储过程:

DROP PROCEDURE IF EXISTS check_user_files;
DELIMITER \\
CREATE PROCEDURE check_user_files(IN p_user_id INT,IN p_file_id CHAR(10))
BEGIN
IF EXISTS(SELECT 1 FROM myTable WHERE user_id = p_user_id AND file_id= p_file_id) THEN
UPDATE myTable SET `file_status`=0 WHERE user_id=p_user_id AND file_id=p_file_id;
ELSE
INSERT INTO myTable(`user_id`,`file_status`,`file_id`)
VALUES (p_user_id,0,p_file_id);
END IF;
END \\
DELIMITER ;

调用存储过程:

CALL check_user_files('1','12');

表 [myTable] 结构:

auto_id  user_id  file_id file_status
1 1 12 1
2 3 12 0
3 1 17 1
4 4 31 1
5 1 41 0
6 4 31 0
7 1 18 1
8 5 11 0
9 1 10 0

我的问题是,我有多个数据要同时检查和插入。例如:

('1','12'),('2','14'),('3','16'),...

但是我不能同时调用存储过程来一次查询所有记录。例如:

CALL check_user_files('2','12');
CALL check_user_files('3','12');
...

只调用第一行存储过程。

那么,我怎样才能同时检查一个查询中的所有记录呢!>

非常感谢!!

最佳答案

可以使用单个调用存储过程来完成,但由于 mysql 不支持数组参数,它会有点难看,因为我们必须传入逗号分隔的 user_id;file_id 标记字符串。唯一的其他选择是多次调用存储过程。

完整脚本在这里: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 ;

希望对你有帮助

关于mysql - 如何在 MySQL 或 PHP 中多次执行相同的存储过程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5449897/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com