甲骨文。使用 case 语句时缺少关键字。错误 00905
Posted
技术标签:
【中文标题】甲骨文。使用 case 语句时缺少关键字。错误 00905【英文标题】:Oracle. Missing keyword when using case statement. Error 00905 【发布时间】:2013-07-25 07:00:30 【问题描述】:自从我引入 CASE 语句以来,我不断收到以下语句的错误“ORA-00905:缺少关键字”,但我无法弄清楚缺少什么。
SELECT
CYCLE_S_FACT_MAIN.STARTTIME,
CYCLE_S_FACT_MAIN.ENDTIME
FROM
CYCLE_S_FACT_MAIN
WHERE
(
CYCLE_S_FACT_MAIN.ENDTIME >
(SELECT SYSDATE,
CASE SYSDATE
WHEN TO_CHAR(SYSDATE, 'HH') < 6 THEN CONCAT(TO_CHAR(SYSDATE, 'DD-MM-YYYY'), ' 06:00:00')
ELSE CONCAT(TO_CHAR(SYSDATE - INTERVAL '1' DAY, 'DD-MM-YYYY'), ' 06:00:00')
END AS SYSDATE
FROM DUAL
)
AND
CYCLE_S_FACT_MAIN.ENDTIME <= SYSDATE
)
【问题讨论】:
【参考方案1】:您混淆了CASE
表达式的两种形式。有一个简单的表达式(当您只想比较表达式是否相等时):
CASE Expr1
WHEN Expr2 THEN ...
WHEN Expr3 THEN ...
ELSE ...
END
还有一个搜索过的CASE
表达式,您想在其中评估单独的谓词:
CASE
WHEN Predicate1 THEN ...
WHEN Predicate2 THEN ...
ELSE ...
END
对于搜索到的CASE
,您不要在CASE
和第一个WHEN
之间指定表达式。
【讨论】:
【参考方案2】:Damien_The_Unbeliever 关于混合大小写样式是正确的,但您也根本不需要子查询,而您拥有的就是返回两列 - 您无法与单个值进行比较。你可以这样做:
WHERE
CYCLE_S_FACT_MAIN.ENDTIME > CASE
WHEN TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')) < 6
THEN TRUNC(SYSDATE) + INTERVAL '6' HOUR
ELSE TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '6' HOUR END
AND CYCLE_S_FACT_MAIN.ENDTIME <= SYSDATE
这会将比较留在两个日期之间,而不是依赖隐式转换。我也用过HH24
;使用 HH
会将中午到下午 6 点之间的时间视为与午夜到早上 6 点之间的时间相同,我敢肯定你不是故意的。
【讨论】:
完美!非常感谢亚历克斯!!这让我意识到 THEN 和 ELSE 语句需要切换【参考方案3】:试一试
SELECT
CYCLE_S_FACT_MAIN.STARTTIME,
CYCLE_S_FACT_MAIN.ENDTIME
FROM
CYCLE_S_FACT_MAIN
WHERE
(
CYCLE_S_FACT_MAIN.ENDTIME >
(SELECT SYSDATE,
CASE
WHEN TO_CHAR(SYSDATE, 'HH') < 6 THEN CONCAT(TO_CHAR(SYSDATE, 'DD-MM-YYYY'), ' 06:00:00')
ELSE CONCAT(TO_CHAR(SYSDATE - INTERVAL '1' DAY, 'DD-MM-YYYY'), ' 06:00:00')
END AS "MY_SYSDATE"
FROM DUAL
)
AND
CYCLE_S_FACT_MAIN.ENDTIME <= SYSDATE
)
有两种可能的错误,一种是期望为CASE WHEN
而不是CASE sysdate WHEN
,第二种是sysdate
作为别名,不能用作别名。
【讨论】:
这给出了一个“值太多”的错误...会不会是因为它返回 SYSDATE 和 MY_SYSDATE,所以它不能评估 CYCLE_S_FACT_MAIN.ENDTIME > (SYSDATE, MY_SYSDATE)?我们如何解决这个问题? @RichardMaguire - 为什么你希望它大于两者?下一个子句说它必须是<= sysdate
,所以它不能同时是> sysdate
。您可能需要退后一步,澄清您要实施的逻辑。
好的,只需要返回一个值,如果当前时间
【参考方案4】:
SELECT TO_CHAR(SYSDATE,'HH'),
CASE
WHEN TO_CHAR(SYSDATE,'HH') < 6
THEN CONCAT(TO_CHAR(SYSDATE, 'DD-MM-YYYY'), ' 06:00:00')
ELSE CONCAT(TO_CHAR(SYSDATE - INTERVAL '1' DAY, 'DD-MM-YYYY'), ' 06:00:00')
END "sysdate" ,
TO_CHAR(SYSDATE, 'HH'),
CONCAT(TO_CHAR(SYSDATE, 'DD-MM-YYYY'), ' 06:00:00')
FROM dual;
12 24-07-2013 06:00:00 12 25-07-2013 06:00:00
【讨论】:
该 CASE 语句返回的值太多,只需要返回一个值,如果当前时间 我给出了有效的查询,而不是要显示的值以上是关于甲骨文。使用 case 语句时缺少关键字。错误 00905的主要内容,如果未能解决你的问题,请参考以下文章
在 where 子句中使用 case 语句的 Oracle Missing 关键字
在 MERGE 语句中使用 CASE:ORA-00905:缺少关键字