2017-01-27 20 views
1

我们将把数据库从10g更新为12c。在这样做之前,我们需要重新审视我们的sql语句,并作为其中的一部分,我们需要检查GROUP BY通过编程发现分组错误

案件的下列行为1:

SELECT abcd_pk, 
    COUNT(abcd_code), 
    ABCD_COUNT 
FROM 
    (SELECT abcd_pk, 
    abcd_code, 
    (SELECT COUNT(abcd_code) FROM ABCD_TABLE 
    ) "ABCD_COUNT" 
    FROM ABCD_TABLE 
) 
GROUP BY abcd_pk, ABCD_COUNT ; 
  1. 工作在10G
  2. WORKS IN 12C

壳体2:

SELECT abcd_pk, 
    COUNT(abcd_code), 
    ABCD_COUNT 
FROM 
    (SELECT abcd_pk, 
    abcd_code, 
    (SELECT COUNT(abcd_code) FROM ABCD_TABLE 
    ) "ABCD_COUNT" 
    FROM ABCD_TABLE 
) 
GROUP BY abcd_pk ; 
  1. 工作在10G
  2. 不起作用IN 12C(ORA-00979:不是GROUP BY表达00979. 00000 - “不是一个GROUP BY表达式”)

我们的代码可以包含像SQL这样不适合的case2。所以我们需要识别这些SQL。我已经准备好了一个SQL列表,其中包含我们项目中使用的GROUP BY(.java文件/程序/函数/视图等)。

要求是通过以下步骤找到GROUP BY问题:一个

  1. 检查列表中的一个获得的SQL。
  2. 查找以编程方式检查SQL列表的替代方法。

选项1需要大量的工作量,努力和时间,但我认为选项2是不可能的。

有什么建议如何进行?

+0

反正我会说坚持案例1。如果遵循通用的GROUP BY规则,则永远不会出错 - “如果指定了GROUP BY子句,则SELECT列表中的每个列引用都必须标识分组列或作为set函数的参数。” – jarlh

回答

0

一种可行的解决方法是将count子查询放入一个聚合函数中, AVG()

SELECT abcd_pk, 
     COUNT(abcd_code), 
     AVG(ABCD_COUNT)  -- use an aggregate to not offend Oracle 
FROM 
(
    SELECT abcd_pk, 
      abcd_code, 
      (SELECT COUNT(abcd_code) FROM ABCD_TABLE) "ABCD_COUNT" 
    FROM ABCD_TABLE 
) 
GROUP BY abcd_pk; 

如果这能解决问题,那么就意味着Oracle的治疗导致常量的子查询已10G12C之间变化。

+0

是的,你说得对,但我的问题不是这样。我知道case2是不正确的,case1是正确的。我们的代码中已经有了一些SQL,比如case2,以前它的工作方式是10g,但目前不能在12c中工作。所以我们想把所有的case2变成case1。所以首先我们需要确定这些SQL。我的问题是如何找到所有这样的SQLs case2? –

+0

这是一个非常难回答的问题,并说明尽量保持查询尽可能符合ANSI标准的价值。如果你这样做,版本的变化不会破坏任何东西。 –