PL / SQL AVG Функция с VS2008, вызывающая «Арифметическая операция, приведшая к переполнению» - PullRequest
1 голос
/ 18 ноября 2010

Я уверен, что пропускаю что-то простое здесь, но в любом случае - я пытаюсь построить процедуру 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;

1 Ответ

2 голосов
/ 20 ноября 2010

Ошибка, по-видимому, вызвана разницей в разрешении десятичных разрядов между Oracle и VS2008.По-видимому, Oracle вернется примерно (не совсем точно) 36 dp, тогда как VS2008 обрабатывает только около 27 dp (опять же, не уверен в точном числе.)

Обтекание оператора AVG с Round (...., 12)вернет номер 12 dp, который примет VS2008.

...