4

我有一个主表(以下称为 SURVEY)和一个详细表(以下称为 ANSWERS)。不出所料,ANSWERS 有 SURVEY 问题的答案。ANSWERS 有一个名为 TEXT 的 VARCHAR2 列。一些 ANSWERS.TEXT 值是真正的文本,但有些实际上是数字。幸运的是,我总是知道哪些行包含文本,哪些包含数字作为文本。

这是它的方式。我无法改变这一点。

过去,当某些 ANSWERS 行被保存时,它们的 TEXT 值被精心挑选并放入正确类型列中的 SURVEY 表中。一个简单的单表选择将获取 SURVEY 和特殊值。

但是现在,随着新应用程序的添加,我们删除了特殊列。相反,我们现在必须取而代之的是获取适当的 ANSWERS 行的 TEXT 值。

我创建了一个模拟旧的琐碎选择语句的查询。它工作得很好......主要是。

这是一个片段:

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 就像蛤蜊一样高兴,因此所有输出都通过 j2 的 to_number() 函数并且看起来不错。但是如果我添加条件,我会失败。

where 子句的“overall_score”部分是根据从网页输入的搜索条件动态添加的。

我需要一些fu来告诉 Oracle 我真的知道我在做什么,请去做。如果有非数字数据,ok,让j2的to_number()失败。凉爽的。但除此之外,就去做吧。

有什么妙语吗?我是承包商,时间快到了。这是一个新要求:-/

4

2 回答 2

10

我认为优化器可能正在将内联视图与查询的其余部分合并,这意味着overall_score > 70可能会针对与视图的其余谓词不匹配的行评估条件,从而命中不包含数值的行在text.

如果发生这种情况,您应该能够通过在查询的第一行添加提示来防止它:

select /*+ NO_MERGE(j2) */ ...

或者,它可能会将谓词推送到视图中,在这种情况下,您将需要 NO_PUSH_PRED 提示。如果您可以为查询生成执行计划,它可能会显示确切的问题是什么。

于 2010-09-16T15:50:58.587 回答
3

我们创建了一个特殊版本的 to_number,它在内部捕获“1722 无效号码”异常并返回 0 而不是。用 sql 中的这个新函数替换 to_number 为我们消除了这个问题。

于 2010-09-16T18:16:44.197 回答