【问题标题】:MySQL: Update table with an IN (@variable) failedMySQL:使用 IN (@variable) 更新表失败
【发布时间】:2019-06-19 14:23:42
【问题描述】:

我正在尝试使用 IN 函数和变量更新表。

变量的内容是一个子查询,它返回每个 STRING 的预期值(即 ID)。当我复制/粘贴更新中的值时,一切都很好。

USE `DB1`;

SET SQL_SAFE_UPDATES = 0;

SET @VAR1 = "STRING1,STRING2,STRING3,STRING4";
SET @VAR2 = (SELECT GROUP_CONCAT(`id`) FROM `tbl_A` WHERE FIND_IN_SET(`description`, @VAR1) AND `fieldtype` = '');

UPDATE `tbl_A`
SET `idaccount` = 2
WHERE `id` IN (@VAR2);

SET SQL_SAFE_UPDATES = 1;

那么为什么当我使用变量时,它只更新第一行?

【问题讨论】:

  • 另外,如果你不是真的需要,我建议不要使用 MySQL 用户变量,因为它们会为查询增加不必要的额外复杂性。因为我很确定您尝试执行 UPDATE tbl_A SET idaccount = 2 WHERE id IN (SELECT id FROM tbl_A WHERE FIND_IN_SET(description, 'STRING1,STRING2,STRING3,STRING4') AND fieldtype = ''); 分离 SQL 查询以使用分而治之并不总是最好的方法
  • @RaymondNijland 这是我可以为我的问题提供的最低限度。我不能给你真正的价值和真正的领域的名字。
  • “这是我可以为我的问题给出的最低限度。我不能给你真正的价值和真正的字段名称”你真的回答了吗?很容易提供一个样本数据集。 不一定是真实数据。它只需要公平地反映手头问题的性质。
  • @RaymondNijland 您的想法不正确,因为您无法更新表并在子查询中使用相同的表。您将不得不像蒂姆·比格莱森(Tim Biegeleisen)那样作弊。
  • "你的想法是不正确的,因为你不能更新表并在子查询中使用同一个表。你将不得不像蒂姆·比格莱森的例子一样作弊。 " 是的@nico,我应该说UPDATE tbl_A SET idaccount = 2 WHERE id IN (SELECT id FROM (SELECT id FROM tbl_A WHERE FIND_IN_SET(description, 'STRING1,STRING2,STRING3,STRING4') AND fieldtype = '') AS a); 这就是为什么我询问示例数据和预期结果,这样我们就不必再猜测了。

标签: mysql sql-update user-variables


【解决方案1】:

变量@VAR2标量变量,不能存储结果集。为此,您需要一个 MySQL 不直接支持的表变量(请注意,其他数据库,例如 SQL Server,确实支持它们)。

但是,您可以内联子查询,它应该可以工作:

SET @VAR1 = "STRING1,STRING2,STRING3,STRING4";

UPDATE tbl_A
SET idaccount = 2
WHERE id IN (SELECT id FROM (
                 SELECT id FROM tbl_A
                 WHERE FIND_IN_SET(description, @VAR1) AND fieldtype = ''
             )x );

请注意,更新的IN 子句之后的子查询被包装了两次,以避免尝试引用正在更新的同一个表的问题。这个技巧实际上实现了子查询,使其独立于更新期间发生的事情。

【讨论】:

  • 为什么首先需要使用 MySQL 用户变量。它在FIND_IN_SET(description, "STRING1,STRING2,STRING3,STRING4") 上增加了额外的不必要的复杂性,当您忘记更改@VAR1 时,下一个使用@VAR1 的查询也将具有那个旧值
  • @RaymondNijland 我同意你所有的 cmets,如果没有必要,应该避免变量。我只是尝试用尽可能接近 OP 原始查询的内容来回答。
  • “我只是尝试用尽可能接近 OP 原始查询的内容来回答。” 我知道我给你一个赞成票,因为答案对什么有效topicstarter 想要或需要,我只是想警告 topicstarter 可能发生的(难以调试)错误。
  • @TimBiegeleisen 正如您所说:如果没有必要,应避免使用变量,我将按照您的建议并查看我的查询以删除所有变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多