【问题标题】:ORA-01722 birt eclipseORA-01722 月食
【发布时间】:2015-09-30 20:27:29
【问题描述】:

我有以下在“Oracle SQL Developer”中工作的查询。

在 BIRT Eclipse 中,我收到 ORA-01722“不是数字”错误。

用 TO_NUMBER() 转换数字没有帮助。你有什么想法吗?

select INSTR_NR, VALID_FROM, PRICE, return, sqrt(ema)* 2.326347874041 as VaR1d
from 
(select INSTR_NR, VALID_FROM, PRICE from

(select DATA_IDC, ATTR_IDC, VALUE as INSTR_NR 
from DLEATTRDAT 
where ATTR_IDC = 'FUND:fund:index_abbi_ref'
and LOCKSTATE = 0) x left join
(select DATA_IDC, VALID_FROM, VALUE as PRICE
from DLEATTRDAT 
where ATTR_IDC = 'FUND:instr:EUR_price') y
on x.INSTR_NR = y.DATA_IDC)

model
         partition by (INSTR_NR)
         dimension by (VALID_FROM)
         measures (PRICE,0 return,0 ema)
         rules
         ( return[any] order by VALID_FROM
           = nvl2
             ( PRICE[cv()-1]
             ,  POWER ( ln ( PRICE[cv()] / (PRICE[cv()-1]) ), 2)
             , POWER (ln ( PRICE[cv()] / (PRICE[cv()-3]) ), 2) )
             ,
            ema[any] order by VALID_FROM
           = nvl2
             ( return[cv()-1]
             ,  .06 * return[cv()] + .94 * ema[cv()-1]
             ,  return[cv()]  ) )  
   order by INSTR_NR, VALID_FROM desc 

【问题讨论】:

  • 您的表varchar2 中的列是否包含数字数据?即使在被其他谓词过滤掉的行中,表中的 any 行是否有非数字数据(即 value 不是被 attr_idc 或 @ 过滤掉的数字的行987654325@谓词)?
  • VALUE 作为 INSTR_NR、ATTR_IDC 和 DATA_IDC 是字符串。 VALID_FROM 是日期。其他都是数字
  • 表中是否存在value 不是数字的行(即使它们被其他谓词过滤掉了)?

标签: eclipse oracle birt


【解决方案1】:

根据您的查询,我得出结论,DLEATTRDAT 表或视图中的列 VALUE 是 VARCHAR2。 在您的查询中,您有时将其用作文本值 (INSTR_NR),有时用作数值 (PRICE)。

简而言之,这是一个数据模型设计缺陷(我可以从经验中看出,我们的应用程序中存在类似问题)。

稍后在您的查询中,您在数值计算中使用了 PRICE。

不幸的是,查询优化器可能会选择在执行数值计算之前或之后评估过滤器限制where ATTR_IDC = 'FUND:instr:EUR_price'

在这种千篇一律的表格中,这是一个常见的陷阱。

在您的情况下,优化器似乎选择首先应用 WHERE 子句,然后进行转换,但是当从 BIRT 调用时,优化器以相反的方式执行,导致 ORA-01722。

这既不是 BIRT 错误,也不是 DB 错误;这是查询的问题,也是我们人类思考 Oracle DB 应该如何工作的方式的问题。

幸运的是,种方法可以在不重新设计数据模型的情况下处理此问题。

AFAIK WITH 子句通常会强制优化器临时存储结果,因此处理此问题的一种方法可能是逻辑上等效但技术上不同的查询:

WITH x as (
  select DATA_IDC, ATTR_IDC, VALUE as INSTR_NR 
  from DLEATTRDAT 
  where ATTR_IDC = 'FUND:fund:index_abbi_ref'
  and LOCKSTATE = 0
),
y as (
  select DATA_IDC, VALID_FROM, VALUE as PRICE
  from DLEATTRDAT 
  where ATTR_IDC = 'FUND:instr:EUR_price'
)
select INSTR_NR, VALID_FROM, PRICE, return, sqrt(ema)* 2.326347874041 as VaR1d
from 
(select INSTR_NR, VALID_FROM, PRICE 
 from x left join y
 on x.INSTR_NR = y.DATA_IDC)

model
         partition by (INSTR_NR)
         dimension by (VALID_FROM)
         measures (PRICE,0 return,0 ema)
         rules
         ( return[any] order by VALID_FROM
           = nvl2
             ( PRICE[cv()-1]
             ,  POWER ( ln ( PRICE[cv()] / (PRICE[cv()-1]) ), 2)
             , POWER (ln ( PRICE[cv()] / (PRICE[cv()-3]) ), 2) )
             ,
            ema[any] order by VALID_FROM
           = nvl2
             ( return[cv()-1]
             ,  .06 * return[cv()] + .94 * ema[cv()-1]
             ,  return[cv()]  ) )  
   order by INSTR_NR, VALID_FROM desc 

查看执行计划。 如果它没有创建 SYS_xxxxx 内联视图,优化器提示可能会有所帮助。

根据 DLEATTRDAT 表的大小,新查询可能比原始查询慢一些。

无论如何,您的查询中还有另一个错误:您正在使用从 VARCHAR2 到 NUMBER 的隐式转换,因为您在数值计算中使用了 PRICE。

因此您应该进一步修改可能的查询并在适当的位置添加明确的 TO_NUMBER。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 2020-05-09
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 2014-04-14
    相关资源
    最近更新 更多