2010-11-18 119 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位數字。

相關問題