【问题标题】:MySQL Error Message: Subquery Returns More than 1 RowMySQL 错误消息:子查询返回多于 1 行
【发布时间】:2014-03-08 23:26:43
【问题描述】:

请您帮我解决这个问题:

SELECT
  (SELECT AES_DECRYPT(cryptoword, SHA2('DatabaseEncryption1', 512)) FROM file_tree) AS cryptoword1,
  (SELECT AES_DECRYPT(name, SHA2(cryptoword1, 512)) FROM file_tree) AS name;

正如主题所说,我收到错误消息说我的子查询返回超过 1 行。我想要实现的是:

  1. 获取特定数据库记录的密码。
  2. 使用该密码解密记录的其余部分。
  3. 对所有满足 WHERE 条件的表记录/多条记录重复该过程,我可以稍后添加

如果我只对一条记录使用查询,我的查询有效。但是,我需要从表中获取多条记录。每条记录都有自己的密码,每行都不同。因此,我的任务是获取特定记录的密码,并使用该密码来解密记录的其余部分。我需要对所有表记录重复此过程。

由于性能原因,所有这些都需要在一个查询中进行格式化。

提前谢谢你。

【问题讨论】:

  • 您说针对特定的数据库记录,但您根本没有过滤您的结果。您的两个子查询都需要一个 WHERE 子句,这将保证只返回 1 条记录。
  • LIMIT 1在每个查询的末尾告诉mysql只返回1行
  • 我明白你的意思。挑战在于,我需要为整个表应用我的子查询。
  • @MatBailie,很棒的评论。这是我最初的目标。但是,在您的查询中解密 name 时,无法识别 cryptoword1。至少 MySql 拒绝了这样的查询。嗯,也许我在任何地方都犯了错误而忽略了它?
  • 你为什么不直接用php来做呢?

标签: mysql sql


【解决方案1】:

在子查询中计算出cryptoword1 的值,然后您可以重用结果来计算外部查询中name 的值。

SELECT
  cryptoword1,
  AES_DECRYPT(name, SHA2(cryptoword1, 512))   AS name
FROM
(
  SELECT
    AES_DECRYPT(cryptoword, SHA2('DatabaseEncryption1', 512)) AS cryptoword1,
    name
  FROM
    file_tree
)
  AS sub_query

【讨论】:

  • 我已经在我上面的问题下面回答了你的推荐。看来您最初的建议已经消失了?你有没有发现里面有错误?我更喜欢你最初的建议。
  • @Bunkai.Satori - 我的评论没有注意到您需要在另一个字段中重新使用cryptoword1 的计算结果。正如您所发现的那样,那个结果当时并不存在。您不控制计算顺序,它被视为并行计算。这意味着你可以SELECT f(x, y) AS a, f(z, a) AS b FROM table。您要么需要一个子查询,如本答案所示,要么您需要在代码中重复自己; SELECT f(x, y) AS a, f(z, f(x, y)) AS b FROM table。然而,即使是 MySQL 也应该优化这个 SQL 以避免多余的工作。
  • 是的,第二个重复的解决方案有效。我已经测试过了。但是每次每个记录列都重新生成我的 cryptoword1 是没有意义的,因为我在表中有多个列。我相信上面这个答案中提出的解决方案会奏效。我现在正在测试它。
  • @Bunkai.Satori - 你假设写SELECT f(x, y) AS a, f(z, f(x, y)) AS b FROM table 导致f(x, y) 被计算两次;大多数优化器会看到重复并在内部重用该值 - SQL 被有效编译,不同的 RDBMS 比其他 RDBMS 做更少或更好的工作。也就是说,它仍然是代码的重复,这通常是最好避免的。这两个答案应该执行相同,这取决于您对哪个更具可读性、可维护性等的看法。
  • @Bunkai.Satori - 如果 更安全 你的意思是 保证某种行为,那么明确总是更安全,是的;例如,如果您安装补丁,您不会遇到更改。而之所以在内部查询中提到name,是因为您在外部查询中使用了它;除了显式选择的字段之外,外部查询对内部查询一无所知。
【解决方案2】:

select 语句中的子查询必须计算为单个值,否则您将收到此错误。这是有道理的,因为您希望填充一个字段的值。

【讨论】:

  • 这如何回答这个问题?你能提供更多细节吗?
  • @Yuck,嗨,Yuck。我已经更新了我的问题。我需要对表中的所有记录重复子查询。我希望,更新将使我的问题更容易理解。
猜你喜欢
  • 1970-01-01
  • 2014-02-15
  • 2017-05-29
  • 1970-01-01
  • 2016-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多