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