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;
你已經有兩件事情在這裏發生,並且它不是立即顯而易見的(對我來說至少)哪一部分引發了算術溢出錯誤。 (1)請刪除'OPEN THEDATA FOR sqlstr'位,並打印出正在生成的SQL。然後,分別運行該SQL並向我們顯示(a)正在運行的SQL,以及(b)實際的輸出/錯誤消息。謝謝:) – 2010-11-19 00:18:29
嗨,感謝您的答覆。實際的錯誤是 - 「算術運算導致溢出。」我想我已經通過用ROUND(...,12)包裝AVG語句來修復它。顯然,(我意識到我沒有提及我使用VS2008),Oracle將返回高達36(?)小數位,但VS2008只能使用27(?)dp。四捨五入到小數點後12位已經解決了這個問題。謝謝您的幫助。 – Bob 2010-11-19 08:36:54
做得很好。我建議你添加你的發現作爲答案,並接受它 - 並用VS2008標記這個問題,因爲它是特定於上下文的,我想。 – 2010-11-20 08:34:47