Я уверен, что пропускаю что-то простое здесь, но в любом случае - я пытаюсь построить процедуру PL / SQL, которая реализует AVG через функцию декодирования, см. Ниже. Я продолжаю получать ошибку арифметического переполнения, но не могу понять, что нужно изменить, чтобы сохранить правильный размер для типа (или даже если это то, что требуется!)
Если я изменю AVG на Count, Sum или Max, все в порядке, поэтому я знаю, что декодирование работает правильно, я просто не уверен, почему AVG не работает. Любые указатели очень ценятся.
Ргдс 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".PRETEST_LOT@PRS_DBLINK LOT,
"PRETEST".PRETEST_MEASURE@PRS_DBLINK MEASURE,
"PRETEST".PRETEST_TEST_PARMS@PRS_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_LOT@PRS_DBLINK PRETEST_LOT, ';
sql_str := sql_str || ' "PRETEST".PRETEST_MEASURE@PRS_DBLINK PRETEST_MEASURE, ';
sql_str := sql_str || ' "PRETEST".PRETEST_TEST_PARMS@PRS_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;