我遇到了一种我无法诊断的奇怪行为。
我有一个Oracle数据库(11g),我在这个数据库中构建了一个视图。此视图返回一个信息列表,该信息列表在问题发生前没有问题,并且在问题发生之后目前处于罚款状态。
假设此视图返回10行。当我在此视图上运行聚合函数时,例如让我们说一个COUNT(*)我得到一个10行的列表,每行显示'Null'而不是一行,数字为10.
这是一个突然开始的问题,没有我故意改变数据库或视图(但这是一个大型企业数据库,并且可能由少数其他人做出改变 - 所有这些当前都否认任何已做出更改)也没有影响视图的已知触发器
此问题不会出现在其他表或其他视图中。我已经尝试在构成最终视图的每个表或视图上运行聚合函数,并且每个表都按预期返回一个数字。
我不确定还有什么可以尝试的。我的Google搜索也没有提供任何线索。我会上传代码,但它很大而且笨重,我也无法开始解释它是如何查看数据的(足以说数据库是法语构建的)
真正让我感到的是视图按预期返回数据,但当我在其上运行聚合函数时(例如SELECT COUNT(*)FROM VIEW_THAT_IS_FAILING),它以这种奇怪的方式失败。有什么想法吗?
查看定义失败:
SELECT x.OBJEXCDE,
x.OBJDSC,
x.CLASSIFICATION,
x.COUNTRY,
NVL(y.MONTH_USAGE, 0) AS MONTH_USAGE,
x.STKQTY,
x.STANDARD_COST
FROM (SELECT a.OBJINCDE, a.OBJEXCDE, a.OBJDSC, NVL(b.STKQTY, 0) AS STKQTY, NVL(c.OBJPRC1VAL, 0) AS STANDARD_COST, NVL(d.OBJCHARVAL, 'Exception') AS CLASSIFICATION,
CASE WHEN TO_CHAR(b.STOREINCDE, '0000') || TO_CHAR(c.OBJRTEINCDE, '000') = ' 0615 130' THEN 'UK'
ELSE 'IRE' END AS COUNTRY
FROM P_OBJ a, P_OBJSTORE b, P_OBJPRC c,
(SELECT a.OBJINCDE, b.OBJCHARVAL
FROM P_OBJ a, (SELECT OBJINCDE, OBJCHARVAL FROM P_OBJCHAR WHERE CHARINCDE = 524) b
WHERE a.OBJINCDE = b.OBJINCDE (+)) d
WHERE a.OBJINCDE = b.OBJINCDE (+)
AND a.OBJINCDE = c.OBJINCDE (+)
AND a.OBJINCDE = d.OBJINCDE (+)
AND TO_CHAR(b.STOREINCDE, '0000') || TO_CHAR(c.OBJRTEINCDE, '000') IN (' 0615 130', ' 1158 284')
AND a.CLASSINCDE IN (83, 84, 126) --New Parts, Repairable Parts, Installation Parts
AND (d.OBJCHARVAL IS NULL OR NVL(c.OBJPRC1VAL, 0) = 0)) x,
W_USAGE_1_MONTH y
WHERE x.OBJINCDE = y.OBJINCDE (+)
AND x.COUNTRY = y.COUNTRY (+)
AND (NVL(y.MONTH_USAGE, 0) + x.STKQTY) > 0
W_USAGE_1_MONTH的定义:
SELECT a.OBJINCDE,
a.OBJEXCDE,
a.OBJDSC,
NVL(b.STKQTY, 0) AS STKQTY,
NVL(c.OBJPRC1VAL, 0) AS STANDARD_COST,
NVL(d.OBJCHARVAL, 'Exception') AS CLASSIFICATION,
CASE WHEN TO_CHAR(b.STOREINCDE, '0000') || TO_CHAR(c.OBJRTEINCDE, '000') = ' 0615 130' THEN 'UK' ELSE 'IRE' END AS COUNTRY
FROM P_OBJ a,
P_OBJSTORE b,
P_OBJPRC c,
(SELECT a.OBJINCDE, b.OBJCHARVAL FROM P_OBJ a, (SELECT OBJINCDE, OBJCHARVAL FROM P_OBJCHAR WHERE CHARINCDE = 524) b WHERE a.OBJINCDE = b.OBJINCDE (+)) d
WHERE a.OBJINCDE = b.OBJINCDE (+)
AND a.OBJINCDE = c.OBJINCDE (+)
AND a.OBJINCDE = d.OBJINCDE (+)
AND TO_CHAR(b.STOREINCDE, '0000') || TO_CHAR(c.OBJRTEINCDE, '000') IN (' 0615 130', ' 1158 284')
AND a.CLASSINCDE IN (83, 84, 126) --New Parts, Repairable Parts, Installation Parts
AND (d.OBJCHARVAL IS NULL OR NVL(c.OBJPRC1VAL, 0) = 0)
答案 0 :(得分:0)
只是为了好玩,请尝试以下方法:
SELECT x.OBJEXCDE,
x.OBJDSC,
x.CLASSIFICATION,
x.COUNTRY,
NVL(y.MONTH_USAGE, 0) AS MONTH_USAGE,
x.STKQTY,
x.STANDARD_COST
FROM (SELECT a.OBJINCDE,
a.OBJEXCDE,
a.OBJDSC,
NVL(b.STKQTY, 0) AS STKQTY,
NVL(c.OBJPRC1VAL, 0) AS STANDARD_COST,
NVL(d.OBJCHARVAL, 'Exception') AS CLASSIFICATION,
CASE
WHEN TO_CHAR(b.STOREINCDE, '0000') || TO_CHAR(c.OBJRTEINCDE, '000') = ' 0615 130' THEN 'UK'
ELSE 'IRE'
END AS COUNTRY
FROM P_OBJ a
LEFT OUTER JOIN P_OBJSTORE b
ON (a.OBJINCDE = b.OBJINCDE)
LEFT OUTER JOIN P_OBJPRC c
ON (a.OBJINCDE = c.OBJINCDE)
LEFT OUTER JOIN (SELECT a.OBJINCDE, b.OBJCHARVAL
FROM P_OBJ a
LEFT OUTER JOIN (SELECT OBJINCDE, OBJCHARVAL
FROM P_OBJCHAR
WHERE CHARINCDE = 524) b
ON (a.OBJINCDE = b.OBJINCDE)) d
ON (a.OBJINCDE = d.OBJINCDE)
WHERE TO_CHAR(b.STOREINCDE, '0000') || TO_CHAR(c.OBJRTEINCDE, '000') IN (' 0615 130', ' 1158 284') AND
a.CLASSINCDE IN (83, 84, 126) AND --New Parts, Repairable Parts, Installation Parts
(d.OBJCHARVAL IS NULL OR
NVL(c.OBJPRC1VAL, 0) = 0)) x
LEFT OUTER JOIN W_USAGE_1_MONTH y
ON (x.OBJINCDE = y.OBJINCDE AND
x.COUNTRY = y.COUNTRY)
WHERE (NVL(y.MONTH_USAGE, 0) + x.STKQTY) > 0
这只是使用ANSI连接语法重新编写的原始视图。试一试,看看它是否有所改变。
也可能是DBA应用了补丁或进行了其他一些影响这一点的变化。
分享并享受。
答案 1 :(得分:0)
虽然支持请求仍然没有得到回应,但我还是弄清楚了解这个问题。
虽然打破视图回到它的基本要素,但我发现当我试图对较小的聚合部分进行聚合时,SQL失败了。因此,W_USAGE_1_MONTH中的聚合导致较大的少数聚合失败,其方式是将一系列NULL值放入多少行的计数,而不是一行计算行数。
虽然我对视图进行了一些修补,但是当我在FROM Clause Select语句中封装了W_USAGE_1_MONTH时,行为似乎已经解决了:
(SELECT OBJINCDE, MONTH_USAGE, COUNTRY FROM W_USAGE_1_MONTH) b
我的感觉是,DBA(我没有立即访问权限)进行了一项更改,这会对处理SQL语句的顺序产生影响。强制在语句使用W_USAGE_1_MONTH视图之前对其进行评估,从而导致操作成功完成。
对于一个奇怪的事件和一个不能解释根本原因的答案来说,这不是一个非常令人兴奋的结局,因为我不知道可能产生哪些影响评估顺序的变化。但是,这可能会帮助其他人查看奇怪行为的评估顺序。