2011-06-24 14 views
10

Korzystam z następującej metody obliczania listy płac za pomocą jdbc, ale błąd "ORA-01008: nie wszystkie zmienne związane" nie jest usuwany."ORA-01008: nie wszystkie zmienne związane" błąd

Masz pomysł?

Używam następujący kod

public double getPayroll(){ 
      ResultSet rs = null; 
      ResultSet rs1 = null; 
      ResultSet rs2 = null; 

      Connection conn = null; 
      PreparedStatement pstmt = null; 
      try { 
        conn = getDBConnection(); 
        double dailyPay=0,basicPay=0,payroll2=0; 
        int houseRent=0,convAllow=0,noOfPresents=0,empId=0; 
        String q = "select e_id from employee"; 
        pstmt = conn.prepareStatement(q); 
        rs = pstmt.executeQuery(); 
        while (rs.next()) { 
         empId=rs.getInt(1); 
         String q1 = "select count(att_status) from attendance where att_status='p'"; 
         pstmt = conn.prepareStatement(q1); 
         rs1 = pstmt.executeQuery(q1); 
         while(rs1.next()){ 
          noOfPresents=rs1.getInt(1); 
          String q2 = "select e_salary,e_house_rent,e_conv_allow from employee where e_id=?"; 
          pstmt = conn.prepareStatement(q2); 
          pstmt.setInt(1,empId); 
          rs2 = pstmt.executeQuery(q2); 
          while(rs2.next()){ 
           dailyPay=rs2.getInt(1)/22; 
           houseRent=rs2.getInt(2); 
           convAllow=rs2.getInt(3); 
           basicPay=dailyPay*noOfPresents; 
           payroll2+=basicPay+houseRent+convAllow; 
          } 
         } 
        } 
        return payroll2; 
      }catch (Exception e) { 
       e.printStackTrace(); 
       return 0.0; 
      } finally { 
       try { 
       rs.close(); 
       pstmt.close(); 
       conn.close(); 
       } catch (Exception e) { 
       e.printStackTrace(); 
       } 
      } 
} 
+0

W którym momencie otrzymujesz ten wyjątek? – RMT

+0

Czy frekwencja jest w jakiś sposób powiązana z pracownikiem?W przeciwnym razie 'select count (att_status)' dla każdego e_id nie ma sensu (jak to nigdy się nie zmieni) –

Odpowiedz

25

problem jest tutaj:

rs2 = pstmt.executeQuery(q2); 

mówisz PreparedStatement wykonać SQL q2, zamiast wykonywania SQL wcześniej przygotowany. To powinno być po prostu:

rs2 = pstmt.executeQuery(); 

Jest to dość częsty błąd, spowodowany głównie przez złe klasy konstrukcji java.sql.Statement i jego podtypy.

Jak @RMT wskazuje zrobić tego samego błędu tutaj:

rs1 = pstmt.executeQuery(q1); 

To nie ma znaczenia tak dużo, ponieważ nie istnieją żadne zastępcze w q1, więc SQL wykonuje jak jest. Wciąż jest jednak nie tak.

Wreszcie, należy rozważyć wywołanie close() na pierwszym PreparedStatement, przed ponownym przypisaniem zmiennej pstmt do innej. Ryzykujesz przeciek, jeśli tego nie zrobisz.

+1

Również rs1 jest podobnym błędem – RMT

+0

Problem został rozwiązany. Dziękuję bardzo za poświęcony czas. Ale jestem zdezorientowany, dlaczego jestem nie otrzymuje wyjątku w tym wierszu kodu rs1 = pstmt.executeQuery (q1); – Adnan

+1

@Adnan - rs1 nie generuje wyjątków, ponieważ q1 nie ma żadnych zmiennych wiążących –

1

Jednym z powodów może być to, że nie można ponownie użyć wystąpienia pstmt w ten sposób. Musisz użyć osobnej instancji PreparedStatement na każdym poziomie pętli.

Czy zdajesz sobie sprawę, że można to zrobić za pomocą tylko jednej instrukcji?

Edit:
Zakładając tam jest relacja między pracownikiem i frekwencji, coś takiego byłoby powrócić sumę w jednym wniosku:

select sum((e_salary/22) * att_count + e_house_rent + e_conv_allow) 
from (
    select emp.e_salary 
      emp.e_house_rent, 
      emp.e_conv_allow, 
      (select count(att.att_status) from attendance att where att.e_id = mp.e_id) s att_count 
    from employee emp 
) t 

Jeśli rzeczywiście frekwencja nie jest powiązany z pracownikiem, po prostu pomiń klauzul where w zagnieżdżonym zaznaczeniu.

+0

Nie, nie jestem świadomy, jak można to zrobić za pomocą pojedynczego przygotowanego oświadczenia. mnie, jak mogę to zrobić za pomocą pojedynczego przygotowanego oświadczenia? – Adnan

1
      pstmt = conn.prepareStatement(q2); 
          pstmt.setInt(1,empId); 
          rs2 = pstmt.executeQuery(q2); 

Utworzoną instrukcję przygotowano już za pomocą kwerendy q2 i powiązano z nią zmienną empId. jeśli teraz wywołasz pstmt.executeQuery (q2), powiązanie zmiennej zostanie utracone. Sterownik JDBC prawdopodobnie analizuje niezwiązany sql q2 po uruchomieniu pstmt.executeQuery (q2).

-1

ZESTAW ZESTAWU TESTCP CP_KEY2 = ?, CP_DESC = ?, CP_MAKER = ?, CP_MAKER_DT = SYSDATE, CP_STATUS = 'M' GDZIE CP_LANGUAGE =? AND CP_ENG_CODE =? AND CP_KEY1 =? AND CP_LANGUAGE =?

W powyższym zapytaniu mamy 7 w parametrze, ale jeśli w twoim kodzie java PreparedStatement ustawiłeś tylko 6 wartości parametrów.

W tym czasie wystąpi również ten błąd.

Powiązane problemy