我有一个主表(以下称为SURVEY)和一个详细信息表(以下称为ANSWERS。)不出所料,ANSWERS可以回答调查问题。 ANSWERS有一个名为TEXT的VARCHAR2列。一些ANSWERS.TEXT值是真正的文本,但有些实际上是数字。幸运的是,我总是知道哪些行包含文本,哪些行包含数字作为文本。
就是这样。我无法改变这一点。
当天,当某些ANSWERS行被保存时,他们的TEXT值被挑选出来并放入正确类型列中的SURVEY表中。一个简单的单表选择将获取SURVEY和特殊值。
但是现在,通过添加新应用程序,我们删除了特殊列。相反,我们现在必须改为获取相应的ANSWERS行的TEXT值。
我创建了一个模拟旧的普通select语句的查询。它的效果很好......主要是。
这是一个片段:
select survey.*,
j2.overall_score
from survey,
(select to_number(trim(ANSWER.text)) overall_score,
survey.id survey_id
from ANSWER,
[edited - more SQL that gets the 'score' row from ANSWERS]) j2
where
survey.id=j2.survey_id
and overall_score > 70
您可能会注意到j2。在真实查询中,有六个这样的列,j1到j6。当我运行查询时,它看起来像一样就像旧查询一样。你不能说它真的是由主/细节组装而成。这是一种解脱!
然而,我的问题是'overall_score> 70'短语导致'1722无效数字'错误。当我不包含短语时,Oracle和clam一样高兴,因此所有输出都通过j2的to_number()函数并且看起来很好。但如果我添加条件,我就会失败。
where子句的'overall_score'部分是根据从网页输入的搜索条件动态添加的。
我需要一些 fu 来告诉Oracle我真的知道我在做什么,请这样做。如果有非数字数据,那么,让j2的to_number()失败。凉。但除此之外,就这样做。
任何明智的话?我是承包商,时间快到了。这是一项新要求: - /
答案 0 :(得分:10)
我认为优化器可能正在将内联视图与查询的其余部分合并,这意味着可以针对与视图的其余谓词不匹配的行评估条件overall_score > 70
,从而命中text
中不包含数值的行。
如果发生了这种情况,您应该可以通过在查询的第一行添加提示来阻止它:
select /*+ NO_MERGE(j2) */ ...
或者,它可以将谓词推入视图,在这种情况下,您需要NO_PUSH_PRED提示。如果您可以为查询生成执行计划,则可能会显示确切的问题。
答案 1 :(得分:3)
我们创建了一个特殊版本的to_number,它在内部捕获'1722无效数字'异常并返回0而不是。在sql中用这个新函数替换to_number为我们消除了这个问题。