2011-08-16 31 views
1

我需要针对Informix IDS 9.x运行动态构建的查询;而WHERE子句大多非常简单,Projection子句可能非常复杂,大量的列和公式适用于列。这里有一个例子:使用DBD捕获错误:: Informix

SELECT ((((table.I_ACDTIME + table.I_ACWTIME + table.I_DA_ACDTIME + table.I_DA_ACWTIME + 
      table.I_RINGTIME))+(table.I_ACDOTHERTIME + table.I_ACDAUXINTIME + 
      table.I_ACDAUX_OUTTIME)+(table.I_TAUXTIME + table.I_TAVAILTIME + 
      table.I_TOTHERTIME)+((table.I_AVAILTIME + table.I_AUXTIME)* 
     ((table.MAX_TOT_PERCENTS/100)/table.MAXSTAFFED)))/(table.INTRVL*60)) 
FROM table 
WHERE ... 

当一些使用的字段包含零时,问题就出现了; Informix的可预见的零错误抛出分裂,但错误信息是不是非常有帮助:

DBD::Informix::st fetchrow_arrayref failed: 
SQL: -1202: An attempt was made to divide by zero. 

在这种情况下,最好是在未能计算返回NULL。除了解析Projection子句并附上CASE ... END中的每个分区尝试之外,是否有任何方法可以实现此目的?如果它在那里,我宁愿使用一些DBD :: Informix的魔法。

回答

2

我不相信你可以用DBD :: Informix或任何其他数据库客户端来解决这个问题,而不需要解析SQL并重写它。没有选择只用/ 0算法忽略列:当发生错误时,整个语句在引擎级失败。

如果它的任何帮助,您可以编写代码来避免/ 0作为DECODE而非CASE ... END,这是一个小更清洁,即:

DECODE(table.MAXSTAFFED, 0, NULL, 
    ((table.MAX_TOT_PERCENTS/100)/table.MAXSTAFFED)))/(table.INTRVL*60))) 
+0

我也这么认为,但是在这样做之前必须检查。感谢DECODE()提示,我对Informix不太熟悉,不知道这个函数。 –

+0

如果Informix支持'NULLIF',那么这将变成NULLIF(...,0),甚至可以被认为是整数。 –

0

从Informix的工作经验,我会说你woud是幸运地得到那种内IDS functionallity的(早期版本的IDS的 - 不早远远超过你的版本 - 有几乎没有任何字符串处理函数没关系复杂的事情。)

我会节省自己的时间,并在内存列表中生成计算。

+0

情况并非如此;我从我无法更改的报告模板中获取预定义的查询。我唯一能做的就是解析和替换,但我不喜欢它,太不可靠。 –

1

DBD :: Informix的是用于Informix的接口数据库管理系统,尽可能的薄(这不是我想要的任何地方,但这是另一个讨论)。这种行为不能合理地由DBD :: Informix(或任何其他访问DBMS的DBD驱动程序)介导;它必须由DBMS自己处理。

IDS不提供一种机制来产生NULL来代替除零错误。这可能是一个合理的功能请求 - 但它最早不会实施到Informix 11.70的后续版本。请注意,Informix Dynamic Server(IDS)9.x比其支持生命周期结束还要好几年(10.00也不受支持)。

+0

好的,如果DBD :: Informix作者说没有魔法,那么没有。谢谢。至于版本,我知道它已经过时了,但在这种情况下升级是没有问题的。此外,它大部分时间都运行得很好,所以即使有可能,升级的动力也不大。 :) –