ORA-00905: 缺少关键字
Posted
技术标签:
【中文标题】ORA-00905: 缺少关键字【英文标题】:ORA-00905: missing keyword 【发布时间】:2015-02-09 10:05:09 【问题描述】:我的表有这些列:
|blo|NotionalCurrency|Notional|Premiumcurrency|Basecurrency|Termcurrency|StructureName|Basemarketprice|Termmarketpriceprecent |Termmarketprice|
我想从这些中获取 blo、货币和价格。下面是我的 SQL:
select blo.opt,
case
when opt.premiumcurrency is not null and opt.structurename is not null then currency = opt.premiumcurrency
case
when opt.notionalcurrency = opt.basecurrency and opt.premiumcurrency = opt.termcurrency then price = opt.termmarketpricepercent / opt.notional
else
case
when opt.premiumcurrency = opt.basecurrency then price = opt.basemarketprice /100
else
price = opt.termmarketpriceprecent /100
end
end
when price = 0 then price = 0.000001
end
FROM interface opt
WHERE opt.notionalcurrency = opt.basecurrency and opt.premiumcurrency = opt.termcurrency;
但我收到错误:ORA-00905: missing keyword
基本上应该使用下面的逻辑来获取/派生SQL来获取三列:Blo、货币和价格:
If notional currency = base currency and premium currency=term currency Then
Price =term market price/notional
currency = notional currency
Else
If notional currency = premium currency then
Price= base market price /100
currency = termcurrency
else
Price=term market price percent /100
currency = notional
end if
end if
if price=0 then
price=0.000001
end if
【问题讨论】:
blo.opt
后面少了一个逗号
第二种情况跟在第一种情况之后,没有 else/case 条件。另外我认为您无缘无故有太多嵌套案例,请edit 并发布您的具体要求
以使现有答案无效的方式编辑您的问题似乎有点粗鲁。现在提出这个问题的人会认为 Bonesist 的答案是无关紧要或错误的,除非他们检查编辑历史记录。
@Alex。道歉。我不想提出另一个问题,这就是为什么。
【参考方案1】:
您在初始 case 语句中缺少 end
。只需在when price = 0 then price = 0.000001
后添加即可
【讨论】:
谢谢。我添加了它现在我得到ORA-00905: missing keyword
@Sathya 已经为您提供了您现在收到缺少关键字错误的原因。他在他的cmets和答案中提出了一些优秀的观点!
@ALL,我已经更新了获取所需 3 列所需的逻辑。提前致谢。【参考方案2】:
这里有很多问题。稍微分解一下:
case
when opt.premiumcurrency is not null
and opt.structurename is not null
根据where
条件,opt.premiumcurrency
不能为空,因此检查不会添加任何内容。
then currency = opt.premiumcurrency
您不能在此处设置值;正如 Arka 所示,您似乎希望这是一个在最终输出中标记为 currency
的表达式。
case
when opt.notionalcurrency = opt.basecurrency
and opt.premiumcurrency = opt.termcurrency
then price = opt.termmarketpricepercent / opt.notional
现在您要查找的是价格,而不是货币,所以这不是前面 case 子句的一部分;这意味着你现在应该有一个end as currency,
。但是您也没有else
条件,这意味着如果opt.structurename
为空,您的货币表达式将为空;不清楚这是否是你想要的。
但是由于您的where
子句,这两个条件都必须为真,这使得整个case
变得多余。同样,您需要一个表达式别名,而不是尝试使用 =
设置值。
else
case
when opt.premiumcurrency = opt.basecurrency
then price = opt.basemarketprice /100
else
price = opt.termmarketpriceprecent /100
end
end
您在此处嵌套了一个案例,因此看起来您正在尝试直接转换 if/elsif/else 构造,而没有考虑 case 的语义实际上是如何工作的。不需要嵌套的 case/end,因为 when/end 可以是封闭 case 的一部分。但是如上所述,第一个when
条件必须始终为真,opt.premiumcurrency = opt.basecurrency
也必须始终为真,所以所有这些也是多余的。
when price = 0 then price = 0.000001
这只是浮动在那里,所以这需要是一个外壳或解码,或者可能是一个least()
,如果该值永远不会是负数。
因此,根据您显示的where
条件,这可以简化为:
select opt.blo,
case
when opt.structurename is not null then opt.premiumcurrency
end as currency,
case
when opt.termmarketpricepercent = 0 then 0.000001
else opt.termmarketpricepercent / opt.notional
end as price
from interface opt
where opt.notionalcurrency = opt.basecurrency
and opt.premiumcurrency = opt.termcurrency;
如果where
子句是临时的,并且您需要更通用的查询,那么它仍然比您创建它更简单:
select opt.blo,
case
when opt.premiumcurrency is not null
and opt.structurename is not null
then opt.premiumcurrency
end as currency, -- still no 'else' so null if structurename is null
decode (
case
when opt.notionalcurrency = opt.basecurrency
and opt.premiumcurrency = opt.termcurrency
then opt.termmarketpricepercent / opt.notional
when opt.premiumcurrency = opt.basecurrency
then opt.basemarketprice /100
else opt.termmarketpricepercent /100
end, 0, 0.000001) as price
from interface opt;
(我已将 blo.opt
交换为 opt.blo
,正如 Sathya 所发现的那样,并且还修复了至少一个列引用中的错字...)
根据您的最新编辑,您希望根据相同的条件选择货币和价格,这在原始查询中并不明显。每种情况只能计算一个值,因此您需要在两个表达式中重复条件,一个是货币,一个是价格;然后如果价格为零,您仍然想更改价格。再次假设 where
是临时的:
select opt.blo,
case
when opt.notionalcurrency = opt.basecurrency
and opt.premiumcurrency = opt.termcurrency
then opt.notionalcurrency
when opt.notionalcurrency = opt.premiumcurrency
then opt.termcurrency
else opt.notionalcurrency
end as currency,
decode (
case
when opt.notionalcurrency = opt.basecurrency
and opt.premiumcurrency = opt.termcurrency
then opt.termmarketpricepercent / opt.notional
when opt.notionalcurrency = opt.premiumcurrency
then opt.basemarketprice / 100
else opt.termmarketpricepercent / 100
end, 0, 0.000001) as price
from interface opt;
价格计算和以前一样,货币表达式已更改以匹配相同的逻辑。不过,您现在似乎丢失了structurename
支票。并且有一个基本假设,即所有货币值都不是空值,真的。
SQL Fiddle 有部分表,没有数据,只是为了显示查询不会出错。
【讨论】:
非常感谢。您的代码返回结果。由于要求似乎发生了一些变化,我会尽快回来。【参考方案3】:试试这个:
SELECT opt.blo,
CASE
WHEN (opt.premiumcurrency IS NOT NULL
AND opt.structurename IS NOT NULL) THEN
currency = opt.premiumcurrency
END,
CASE
WHEN (opt.notionalcurrency = opt.basecurrency
AND opt.premiumcurrency = opt.termcurrency) THEN
price = opt.termmarketpricepercent / opt.notional
WHEN price = 0 THEN
price = 0.000001
WHEN opt.premiumcurrency = opt.basecurrency THEN
price = opt.basemarketprice / 100
ELSE
price = opt.termmarketpriceprecent / 100
END
FROM interface opt
WHERE opt.notionalcurrency = opt.basecurrency
AND opt.premiumcurrency = opt.termcurrency;
【讨论】:
【参考方案4】:我对这个查询有几点看法:
-
据我了解,opt 是您的表的别名,要获取属性,您应该编写 opt.blo 而不是 blo.opt。
case 语句应包含 case 值,例如您使用 case 语句的列名
我已尝试修改代码。未编译,因此可能存在语法错误。看看就好。
select opt.blo,
case opt.currency
when opt.premiumcurrency is not null and opt.structurename is not null
then opt.premiumcurrency
end as Currency,
case opt.price
when opt.notionalcurrency = opt.basecurrency and opt.premiumcurrency = opt.termcurrency then opt.termmarketpricepercent / opt.notional
when opt.premiumcurrency = opt.basecurrency then opt.basemarketprice /100
when price = 0 then price = 0.000001
else
opt.termmarketpriceprecent /100
end as Price,
FROM interface opt
WHERE opt.notionalcurrency = opt.basecurrency and opt.premiumcurrency = opt.termcurrency;
【讨论】:
谢谢。我运行你的代码,但我仍然得到ORA-00905
如果您还尝试在when opt.premiumcurrency ...
条件中指定列,case opt.currency
是无效语法。
@Alex 我没有在 when 条件的任何地方使用列名
@ALL,我已经更新了获取所需 3 列所需的逻辑。提前致谢。
@ArkaBanerjee - 你在混音simple and searched case expression syntax。无论如何都没有一个简单的opt.currency
列,并且由于正在测试两件事,所以这不是一个简单的案例;它应该只是case when opt.premiumcurrency is not null ...
作为搜索案例?以上是关于ORA-00905: 缺少关键字的主要内容,如果未能解决你的问题,请参考以下文章