2010-11-18 56 views
1

我确定我在这里忽略了一些简单的东西,但无论如何 - 我试图构建一个通过一个实现AVG的PL/SQL过程解码功能,见下文。我一直得到一个算术溢出的错误,但无法弄清楚需要改变以保持该类型的正确大小(或者即使这是需要的!)使用VS2008导致“算术运算导致溢出”的PL/SQL AVG函数

如果我将AVG更改为Count,Sum或Max,全部是好的,所以我知道解码工作正常,我只是不知道为什么AVG不是。任何指针不胜感激。出现

RGDS BBZ

PROCEDURE GET_DATAMEANS (
    fLOTCODE IN VARCHAR2, 
    fFROMDATE IN DATE, 
    fTODATE IN DATE, 
    THEDATA OUT SYS_REFCURSOR) IS 

    TYPE loc_array_type IS TABLE OF VARCHAR2(40); -- array type 
    sql_str VARCHAR2(10000); -- SQL statement 
    loc_array loc_array_type;  -- array for test names 

    BEGIN -- executable part starts here 

     -- get the test names for the given lot code 
     SELECT 
      PT_TESTNAME BULK COLLECT INTO loc_array 
     FROM 
      (SELECT DISTINCT 
       TESTPARMS.PT_TESTNAME, TESTPARMS.PT_TESTNUM 
       FROM "PRETEST"[email protected]_DBLINK LOT, 
       "PRETEST"[email protected]_DBLINK MEASURE, 
       "PRETEST"[email protected]_DBLINK TESTPARMS 
       WHERE (LOT.PT_LOTSQ = MEASURE.PT_LOTSQ) 
       AND (MEASURE.PT_LOTSQ = TESTPARMS.PT_LOTSQ) 
       AND (MEASURE.PT_TESTNUM = TESTPARMS.PT_TESTNUM) 
       AND (LOT.PT_LOTID = fLOTCODE) 
       ORDER BY PT_TESTNUM); 

     -- build the SQL string 
     sql_str := ''; 
     sql_str := sql_str || 'SELECT '; 
     sql_str := sql_str || ' PRETEST_LOT.PT_LOTID, '; 
     sql_str := sql_str || ' PRETEST_LOT.PT_LOCTYPE, ' ; 
     sql_str := sql_str || ' PRETEST_LOT.PT_TESTDATE, '; 

     -- add the decodes for column headings 
     FOR i IN loc_array.first..loc_array.last LOOP 
      sql_str := sql_str 
       || ' AVG (decode (PRETEST_TEST_PARMS.PT_TESTNAME, ''' 
       || loc_array(i) || ''', PRETEST_MEASURE.PT_MEAS_VALUE , null)) ' 
       || loc_array(i); 
       IF (i < loc_array.last) THEN 
        sql_str := sql_str || ', '; 
       END IF; 
     END LOOP; 

     -- build the remainder of the SQL 
     sql_str := sql_str || ' FROM '; 
     sql_str := sql_str || '  "PRETEST".PRETEST_[email protected]_DBLINK PRETEST_LOT, '; 
     sql_str := sql_str || '  "PRETEST"[email protected]_DBLINK PRETEST_MEASURE, '; 
     sql_str := sql_str || '  "PRETEST"[email protected]_DBLINK PRETEST_TEST_PARMS '; 

     sql_str := sql_str || ' WHERE '; 
     sql_str := sql_str || '  PRETEST_LOT.PT_LOTSQ = PRETEST_MEASURE.PT_LOTSQ AND '; 
     sql_str := sql_str || '  PRETEST_MEASURE.PT_LOTSQ = PRETEST_TEST_PARMS.PT_LOTSQ AND '; 
     sql_str := sql_str || '  PRETEST_MEASURE.PT_TESTNUM = PRETEST_TEST_PARMS.PT_TESTNUM AND '; 
     sql_str := sql_str || '  PRETEST_LOT.PT_LOCTYPE=''9A08-55/T'' AND '; 
     sql_str := sql_str || '  PRETEST_LOT.PT_TESTDATE Between :fFROMDATE And :fTODATE '; 

     sql_str := sql_str || ' GROUP BY '; 
     sql_str := sql_str || '  PRETEST_LOT.PT_LOTID, '; 
     sql_str := sql_str || '  PRETEST_LOT.PT_LOCTYPE, '; 
     sql_str := sql_str || '  PRETEST_LOT.PT_TESTDATE '; 

     sql_str := sql_str || ' ORDER BY '; 
     sql_str := sql_str || '  PRETEST_LOT.PT_TESTDATE '; 

     -- run the query 
     OPEN THEDATA FOR sql_str USING fFROMDATE, fTODATE; 

END GET_DATAMEANS; 
+0

你已经有两件事情在这里发生,并且它不是立即显而易见的(对我来说至少)哪一部分引发了算术溢出错误。 (1)请删除'OPEN THEDATA FOR sqlstr'位,并打印出正在生成的SQL。然后,分别运行该SQL并向我们显示(a)正在运行的SQL,以及(b)实际的输出/错误消息。谢谢:) – 2010-11-19 00:18:29

+0

嗨,感谢您的答复。实际的错误是 - “算术运算导致溢出。”我想我已经通过用ROUND(...,12)包装AVG语句来修复它。显然,(我意识到我没有提及我使用VS2008),Oracle将返回高达36(?)小数位,但VS2008只能使用27(?)dp。四舍五入到小数点后12位已经解决了这个问题。谢谢您的帮助。 – Bob 2010-11-19 08:36:54

+0

做得很好。我建议你添加你的发现作为答案,并接受它 - 并用VS2008标记这个问题,因为它是特定于上下文的,我想。 – 2010-11-20 08:34:47

回答

2

误差通过在Oracle和VS2008之间的小数位分辨率的差异而引起的。显然,甲骨文将返回(不知道确切)36 dp,而VS2008只处理27 dp(再次,不确定确切的数字)。

包装AVG语句Round(....,12)将返回VS2008将接受的12位数字。

相关问题