2010-11-18 24 views
1

Ben burada basit bir şey bakan değilim, ama yine de - Ben AVG uygulayan bir PL/SQL yordamı oluşturmak için çalışıyorum işlevini çözme, aşağıya bakın. Bir aritmetik taşma hatası almaya devam ediyorum ancak tür için doğru boyutu tutmak için ne gerekli değiştiğini anlayamıyorum (veya gerekli olan bu olsa bile!)PL/SQL AVR İşlevi "Aritmetik işlem bir taşma ile sonuçlandı" hata neden VS2008 "

AVG'yi Say, Toplam veya Maks olarak değiştirirsem iyi, bu yüzden decode doğru çalıştığını biliyorum, sadece AVG neden olmadığından emin değilim. Herhangi bir işaretçi büyük beğeni topladı.

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"[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

Burada iki şeyiniz var ve bu bölüm aritmetik taşma hatasını yükseltmek için hemen belli değil (en azından benim için). (1) lütfen sqlstr' bit için OPEN THEDATA'yı kaldırın ve sadece oluşturulmuş olan SQL'i yazdırın. Ardından, bu SQL'i ayrı ayrı çalıştırın ve bize (a) çalıştırılan SQL'i ve (b) gerçek çıktı/hata iletisini gösterin. Teşekkürler :) –

+0

Merhaba, cevabınız için teşekkürler. Gerçek hata - "Aritmetik işlem bir taşma ile sonuçlandı." Sanırım şimdi AVG deyimini ROUND (..., 12) ile silerek düzeltdim. Görünüşe göre, (ve ben VS2008 kullanmaktan bahsetmemiştim), Oracle 36 (?) Ondalık basamağa dönecek, ancak VS2008 sadece 27 (?) Dp kullanabilir. 12 ondalık basamağa yuvarlama problemi iyileştirdi. Yardım için teşekkürler. – Bob

+0

bununla iyi iş çıkardı. Bulgularınızı bir yanıt olarak eklemenizi ve kabul etmenizi öneririm - ve bu soruyu VS2008 ile etiketleriz, çünkü bu konuya özgüdür. –

cevap

2

hata Oracle ve VS2008 arasındaki ondalık yer çözünürlükte bir farkın sebep olduğu görülmektedir. Görünüşe göre, Oracle (tam olarak emin değilim) 36 dp etrafında dönecektir, ancak VS2008 sadece 27 dp (yine tam sayısından emin değil) olarak işleyecektir.

AVG deyimini Yuvarla ile Döndürme (...., 12) geri dönecektir VS2008'in kabul edeceği 12 dp'lik bir sayı.