【问题标题】:MySQL nested CASE error I need help with?MySQL 嵌套 CASE 错误我需要帮助吗?
【发布时间】:2010-03-29 06:53:12
【问题描述】:

我在这里尝试做的是:如果 $done 中标识的表 todo 中的记录在列 recurinterval 中有一个值,则重置 date_scheduled 列 ELSE 只需将这些记录的 status_id 列设置为 6。

这是我从 mysql_error() 得到的错误...

您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 2 行的“CASE recurinterval != 0 AND recurinterval IS NOT NULL THEN SET date_sche”附近使用正确的语法

我怎样才能使这个声明有效?

UPDATE todo 
CASE recurinterval != 0 AND recurinterval IS NOT NULL THEN
SET date_scheduled = CASE recurunit
WHEN 'DAY' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval DAY)
WHEN 'WEEK' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval WEEK)
WHEN 'MONTH' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval MONTH)
WHEN 'YEAR' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval YEAR)
END
WHERE todo_id IN ($done) 
ELSE 
SET status_id = 6 WHERE todo_id IN ($done)
END

在我进行上述修改之前,以下 mySQL 语句运行良好。

UPDATE todo 
SET date_scheduled = CASE recurunit
WHEN 'DAY' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval DAY)
WHEN 'WEEK' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval WEEK)
WHEN 'MONTH' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval MONTH)
WHEN 'YEAR' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval YEAR)
END
WHERE todo_id IN ($done) 
AND recurinterval != 0 
AND recurinterval IS NOT NULL

【问题讨论】:

  • 感谢大家,你们都很好地帮助了我。看起来我们都同意 wimvds。 :)

标签: php mysql linux nested case


【解决方案1】:

问题是您正在尝试仅使用一个查询来做 afaik 无法做到的事情。您想根据 recurinterval 字段的值更新 2 列中的 1 列。所以基本上你应该把它分成2个查询,第一个就是你有的那个。

UPDATE todo 
SET date_scheduled = CASE recurunit
WHEN 'DAY' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval DAY)
WHEN 'WEEK' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval WEEK)
WHEN 'MONTH' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval MONTH)
WHEN 'YEAR' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval YEAR)
END
WHERE todo_id IN ($done) 
AND recurinterval != 0 
AND recurinterval IS NOT NULL

第二个将用于其他行:

UPDATE todo 
SET status_id = 6
WHERE todo_id IN ($done) 
AND (recurinterval = 0 
OR recurinterval IS NULL)

如果您运行这些查询(很可能您希望在事务中运行它们,以便在其中一个查询期间发生错误时可以回滚更改),您应该会得到您想要的结果。

【讨论】:

  • 你的建议就是我现在正在做的。因为“WHERE todo_id IN ($done)”是多余的,所以在我看来这两个查询可以合并。我不知道如何实施 Nick Gorbikoff 关于使用 IF 进行流量控制的建议。你怎么看?
  • 更新 2 个字段之一的流控制功能是 AFAIK 无法使用 SQL 实现的。是的,WHERE todo_id IN ... 是相同的,但是您也在 recurinterval 上进行过滤,因此您实际上是在尝试一次更新 2 组不同的记录。
【解决方案2】:

我认为您需要在第一个 CASE 关键字之后添加“WHEN”。所以第一行的开头是:

UPDATE todo CASE WHEN recurinterval !=0 AND ...

【讨论】:

  • 我尝试了您的建议,但收到此错误:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 2 行的“CASE WHEN recurinterval != 0 AND recurinterval IS NOT NULL THEN SET date”附近使用正确的语法
【解决方案3】:

在我看来,您在修改语句 CASE recurinterval != 0 AND recurinterval IS NOT NULL THEN 中的第一个案例实际上应该是 IF

【讨论】:

  • 我就您的建议向 wimvds 的回答发表了评论。我测试了 IF 但收到 mysql_error(): Query is empty。我的代码。 “更新 todo IF recurinterval != 0 AND recurinterval IS NOT NULL THEN SET date_scheduled = CASE recurunit WHEN 'DAY' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval DAY) WHEN 'WEEK' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval WEEK) WHEN 'MONTH' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval MONTH) WHEN 'YEAR' THEN DATE_ADD(date_scheduled, INTERVAL recurinterval YEAR) END WHERE todo_id IN ($done) ELSE SET status_id = 6 WHERE todo_id IN ($done) END IF";
  • 也像这样带有括号 IF (recurinterval != 0 AND recurinterval IS NOT NULL) THEN 。 . .我猜 wimvds 的回答是正确的。
  • @AK - 您使用了错误的 IF 语句。您应该使用这个: IF(...) dev.mysql.com/doc/refman/5.0/en/… - 您与 IF ... END IF dev.mysql.com/doc/refman/5.0/en/if-statement.html 混淆了 - 它们是不同的 IF 语句 - 并且具有不同的上下文和用途。抱歉我没说清楚。
  • 好的,我认为 VMVDS 的评论是正确的,因为它使代码更简洁,并且如果其他人需要这样做,则更容易阅读。现在我看了你的陈述——我认为可以用 IF 来做到这一点(但你的陈述会被夸大其词)——你试图评估一个字段并设置另一个字段——而 IF 旨在更新该字段您正在尝试根据条件进行设置。因此,您可以使用 if 语句同时更新 date_scheduled 而不是 status_id,而无需在 IF 语句中运行子查询 - 所以我的投票是坚持使用 VMVDS
猜你喜欢
  • 2016-02-11
  • 1970-01-01
  • 2011-09-02
  • 1970-01-01
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 2018-12-30
相关资源
最近更新 更多