使用ID列表更新多行记录

8

我需要根据Id更新表中的多行数据。在存储过程中,我创建了一个varchar变量来保存Ids列表。

现在,在表中我有Ids为1、2的条目。varchar变量的值为1,2;因此,我期望以下查询不会更新任何行。

UPDATE mytbl
SET flag = 1
WHERE Id IN (IdList); -- Here IdList has value '1,2'

但是这里ID为2的行正在被更新。选择查询也返回相同的行。 我尝试将IdList连接为"'1','2'",然后它会返回两行(ID为1和2)。 Id的数据类型是int。是否有适当的方法来维护整数列表?


2
IdList的值必须是'1','2'而不是'1,2' - Deepu
在第二种方法中,我这样做了,但它返回了两行。 - benjamin54
1
你实际上从哪里获取id列表?是从数据库中获取的数据,还是从“外部”获取的? - Olli
@Olli,从数据库中获取。 - benjamin54
@benjamin54 我知道这并没有什么用,但你应该考虑创建一个表格来存储这种信息,以便更容易地检索,而不是使用逗号分隔的列表。 - Olli
5个回答

13

只需将ID作为整数使用,如下所示:

UPDATE mytbl
SET flag = 1
WHERE id in (1,2,3,....)

2
我正在创建一个包含要更新的ID的列表(varchar)。但是它没有起作用。我的列表应该长什么样? - benjamin54
据我所记,MySQL 中没有可用的分割函数,因此您确实需要从外部提供该列表。 - Olli

6

试试这个:

UPDATE mytbl
SET flag = 1
WHERE @IdList LIKE CONCAT('%,',Id,',%');

请注意您的varchar列表@IdList必须以逗号开头和结尾(例如,1,2,20,30,)。

0
你应该尝试使用左连接,因为你正在获取一个ID的@table类型参数,这将提供更快和更可靠的结果 :)
UPDATE 
    mytbl
SET
    flag = 1
FROM
    @IdList idL
    LEFT JOIN mytbl mTbl ON mTbl.ID = idL.Table_ID 

0

这也是可行的,在这里你不需要在定义变量的开头和结尾加逗号。

SET @IdList = "1,2";

UPDATE mytbl
SET flag = 1
WHERE FIND_IN_SET(Id, @IdList);

0
动态生成子查询,其中列表不是VARCHAR类型,而是查询文本的一部分。即在高级语言(perl/python/php)中实现此功能。

这有点像SQL注入,因为IN条件只能在将varchar变量作为字符串粘贴时才起作用:你不能将其作为变量绑定。 - davek
如果ID列表来自外部来源(Web界面/服务),则会发生注入。当它在软件内部生成时,就没有注入的风险。 - i486
谢谢回复。但是我需要在过程本身中决定这些ID。 - benjamin54
然后,您可以使用游标来处理VARCHAR并提取每个ID。将其存储在临时表中,然后运行查询连接到临时表。在游标循环中使用LOCATE和SUBSTRING来拆分ID。 - i486
谢谢,我知道使用临时表的方法是可行的,但我想知道是否有其他简单的替代方法。所以我发了这个问题。 - benjamin54

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接