将相同字段的值列表发送到MySQL存储过程

时间:2011-08-25 17:31:43

标签: php mysql

我有一个MySQL表,其中ID为主键,而其他非重要字段。 我想要做的是通过发送要删除的ID列表作为存储过程的参数来删除多个记录。

我知道如何手动执行此操作(直接在PHP中构建查询),但我想避免这种情况,并直接在数据库中执行所有SQL。

尝试搜索SO但找不到任何相关问题。对不起,如果这是重复的。

由于

3 个答案:

答案 0 :(得分:3)

根据http://dev.mysql.com/doc/refman/5.1/en/faqs-stored-procs.html#qandaitem-B-4-1-17,你不能直接这样做。

但我认为你可以尝试以下技巧:

  1. 在php中创建你的id字符串,例如'id1,id2,id3'。
  2. 使用预备声明在飞行中绑定此sting。
  3. 也许有帮助。

答案 1 :(得分:2)

您可以尝试类似

的内容
DELETE FROM sometable WHERE FIND_IN_SET(idfield, @param)

不知道这是否有效(并且现在无法访问mysql实例进行测试)。基本上问题是,如果你将一个以逗号分隔的值列表传入一个参数,它只是一个字符串内的一个字符串,并且执行WHERE id IN ('1,2,3')会失败,因为那只是一个简单的字符串而不是与WHERE id IN (1,2,3)完全相同。 find_in_set()函数应该处理这个问题。

答案 2 :(得分:1)

我给@Marc B +1了巧妙使用FIND_IN_SET()。它将无法使用索引,因此性能不会很好,但它应该可以工作。

另一个solution可以工作(但也会很慢,因为它不能使用索引):

DELETE FROM sometable 
WHERE CONCAT(',', param, ',') LIKE CONCAT('%,', idfield, ',%')

@Andrej L描述的解决方案实际上并不是参数绑定,而是将存储过程参数的插值转换为preparing之前的动态SQL字符串。

SET sql = CONCAT('DELETE FROM sometable WHERE idfield IN (', param, ')');
PREPARE stmt FROM sql;
EXECUTE stmt;

您无法使用单个参数参数化值列表,即使参数的值看起来像逗号分隔的整数列表。

插值可以正常工作,从索引中受益,但要小心过滤字符串,使其只包含 数字和逗号。否则,您会引入SQL注入的重大风险(揭穿有些人认为存储过程本质上更安全的说法)。