最近单位的数据库要从db2转到oracle。我在转换sql语句时,发现一个非常奇怪的问题。请各位帮忙看看。同样的sql语句在db2环境下运行正常,而到了oralce10g下,却出现不可思议的情况,但是在9i下却正常。我怀疑是不是10g有bug。
sql原文:
drop table Fact_XHG12_2006_10;
create table Fact_XHG12_2006_10(
TimeCode Char(6),
IEFlag Char(1),
CustomCode Char(4),
CityCode Char(4),
EntTypeCode Char(4),
TradeTypeCode Char(4),
MakerCountryCode Char(5),
ProductCode Char(10),
Quantity NUMBER(13),
Money NUMBER(13),
SumQ NUMBER(13),
SumM NUMBER(13) 
) nologging;
drop table Temp_Fact_XHG12;
create table Temp_Fact_XHG12(
TimeCode Char(6),
IEFlag Char(1),
CustomCode Char(4),
CityCode Char(4),
EntTypeCode Char(4),
TradeTypeCode Char(4),
MakerCountryCode Char(5),
ProductCode Char(10),
Quantity NUMBER(13),
Money NUMBER(13),
SumQ NUMBER(13),
SumM NUMBER(13) 
) nologging;
insert into Temp_Fact_XHG12 
select main.TimeCode, 
main.IEFlag, 
main.CustomCode, 
main.CityCode,
main.EntTypeCode,
main.TradeTypeCode,
main.MakerCountryCode,
main.ProductCode,
main.Quantity,
main.Money,
main.SumQ,
main.SumM 
from MAIN_2006_10_XHG12 main,
Base_Product_HGHS_2006 hs
where main.productcode = hs.productcode;
commit;update Temp_Fact_XHG12 set CityCode = substr(citycode,1,2)||'99' 
where CityCode in ('1303','3205','3206','3207','3303','3706','4404','4405','4408','4505','5107','6546');
commit;insert into Fact_XHG12_2006_10 
select TimeCode, 
IEFlag, 
CustomCode, 
CityCode,
EntTypeCode,
TradeTypeCode,
MakerCountryCode,
ProductCode,
sum(Quantity),
sum(Money),
sum(SumQ),
sum(SumM) 
from Temp_Fact_XHG12 
group by TimeCode, 
IEFlag, 
CustomCode, 
CityCode,
EntTypeCode,
TradeTypeCode,
MakerCountryCode,
ProductCode;
commit;drop table Fact_XHG12_New_2006_10;
create table Fact_XHG12_New_2006_10(
TimeCode Char(6),
IEFlag Char(1),
CityCode Char(4),
EntTypeCode Char(4),
TradeTypeCode Char(4),
MakerCountryCode Char(5),
ProductCode Char(10),
Quantity NUMBER(13),
Money NUMBER(13),
SumQ NUMBER(13),
SumM NUMBER(13) 
) nologging;insert into Fact_XHG12_New_2006_10 
select TimeCode,
IEFlag,
CityCode,
EntTypeCode,
TradeTypeCode,
MakerCountryCode, 
ProductCode, 
sum(Quantity),
sum(Money),
sum(SumQ),
sum(SumM) 
from Fact_XHG12_2006_10 
group by TimeCode,
IEFlag,
CityCode,
EntTypeCode,
TradeTypeCode,
MakerCountryCode, 
ProductCode;
commit;以上操作分别对9i和10g进行。
执行结束后,进行查询a1=select sum(summ) from MAIN_2006_10_XHG12;
a2=select sum(summ) from Fact_XHG12_2006_10;
a3=select sum(summ) from Fact_XHG12_New_2006_10;b1=select count(*) from MAIN_2006_10_XHG12;
b2=select count(*) from Fact_XHG12_2006_10;
b2=select count(*) from Fact_XHG12_New_2006_10;a1 a2 a3 b1 b2 b3
10g 1424949842331 1419138799106 1417534542265 10109949 4682979 3844876
9i 1424949842331 1424949842331 1424949842331 10109949 4682979 3844876发现问题:10g的查询结果不正确。而9i的结果正确分别将9i和10g中的Fact_XHG12_New_2006_10表的列summ导出。
使用UltraEdit软件进行比较,发现两者相差明显。有些值9i有,10g没有。而有些值10g有,9i没有。
比如,summ=399616,该值在9i存在,而在10g中没有。
难道说10g和9i对group by语句的处理有什么区别。
如何解决这个问题,恳请大家帮助。不胜感激。
以上四条语句的结果应该完全一样。
但是奇怪的事情发生了。在3种条件下结果不一样。
DB2 V8 一样
Oracle 9i 一样
Oracle 10g 不一样表MAIN_2006_10_XHG12的数据有1000万行左右。
还有一个现象是,当我把原始数据降到50万行时,Oracle10g 下的计算结果就开始正确了。
所以我怀疑是不是Oracle10g存在未解决的Bug。不知道大家是不是遇到过此类问题。
非常着急。恳请回复。

解决方案 »

  1.   

    确定3个数据库中的数据完全一致么?
    楼主确定不是由于数据不一致的原因导致的么
    9i的group by col1, col2,... 执行的时候,默认把记录集order by col1, col2, ...进行排序
    10g不会, 楼主比较数据的时候最好加上排序再导出进行比较
      

  2.   

    应该是排序规则影响的,lz在insert时加上order by试试
      

  3.   

    谢谢1,2楼,在insert时加上order by果然可以,不过有新问题,为什么会出现这种情况,顺序不对不应该影响结果,10g的group by 采用的是hash算法,9i是sort算法,难道hash算法有什么问题。还有有没有什么方法让10g的gruop by 还采用sort算法,就是不用加order by我试了两种方法都不行。
    方法一:
    Alter system set optimizer_features_enable='10.1.0' scope=spfile; 
    方法二:
    Alter system set "_gby_hash_aggregation_enabled"=false scope=spfile; 
      

  4.   

    顺序不对确实不应该影响结果,楼主非常肯定数据源完全一致么,比较原始表数据,是否也是完全一致的?楼主指定了scope=spfile,那么就不是立即生效的,而是重启数据库后该修改才会生效的
      

  5.   

    数据肯定完全一致,现在的问题是同在10g下sql文加上order by 和不加order by得出的结果都不一样,加上order by结果是对的,很奇怪,难道10g的gruop by 在数据量大的时候会出错。
      

  6.   

    没有碰到过加上order by 和不加的结果不相同(不含排序)
    楼主你的os, oracle version?
      

  7.   

    os:xp
    oracle version:10.2
    在sqlplus中执行Alter system set "_gby_hash_aggregation_enabled"=false问题可以解决。
    说明oracle10.2中group by 的hash算法在数据量非常大的时候有冲突现象发生。
    至于楼上提出的问题:我觉得说明oracle10.2中group by和order by 同时存在的时候group by 子句用的根本不是hash算法,还是原来的sort算法