2011-06-24 34 views
10

我正在使用以下方法通过使用jdbc计算工资单,但“ORA-01008:并非所有变量绑定”错误不会被删除。“ORA-01008:并非所有变量绑定”错误

有什么想法吗?

我使用下面的代码

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

在什么时候你会得到这个例外? – RMT

+0

是否出席与员工有某种联系?否则,每个e_id的'select count(att_status)'没有任何意义(因为它永远不会改变) –

回答

25

你的问题是在这里:

rs2 = pstmt.executeQuery(q2); 

你告诉PreparedStatement执行SQL q2,而不是执行先前准备的SQL。这应该仅仅是:

rs2 = pstmt.executeQuery(); 

这是一个相当常见的错误,造成主要由java.sql.Statement及其亚型坏一流的设计。

由于@RMT所指出的,你在这里同样的错误:

rs1 = pstmt.executeQuery(q1); 

这不那么重要了,因为有在q1没有占位符,所以SQL执行原样。但它仍然是错误的。

最后,您应该考虑在第一个PreparedStatement上调用close(),然后再将pstmt变量重新分配给另一个变量。如果你不这样做,你会冒险泄漏。

+1

也rs1 theres类似的错误 – RMT

+0

问题已经解决。非常感谢您的时间。但我很困惑,为什么我在这行代码中没有得到异常rs1 = pstmt.executeQuery(q1); – Adnan

+1

@Adnan - rs1不会抛出异常,因为q1没有任何绑定变量 –

1

其中一个原因可能是您不能像这样重新使用pstmt的实例。您必须在循环的每个级别中使用单独的PreparedStatement实例。

您是否知道只需一条语句即可完成此操作?

编辑
假设有这样的员工考勤,东西之间的关系将返回在单个请求的总和:

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 

如果确实上座率不挂员工,只是省略嵌套select中的where子句。

+0

不,我不知道如何使用单个预处理语句来完成。我如何使用单个准备好的语句来做到这一点? – Adnan

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

您已经使用查询q2创建了准备语句并将变量empId绑定到它。如果您现在调用pstmt.executeQuery(q2),则变量绑定会丢失。执行pstmt.executeQuery(q2)时,JDBC驱动程序可能会解析未绑定的sql q2。

-1

UPDATE TESTCP SET CP_KEY2 =?,CP_DESC =?,CP_MAKER =?,CP_MAKER_DT = SYSDATE,CP_STATUS ='M'WHERE CP_LANGUAGE =? AND CP_ENG_CODE =? AND CP_KEY1 =?和CP_LANGUAGE =?

在上面的查询中,我们有7个参数,但是如果在您的java代码PreparedStatement中只设置了6个参数值。

那个时候也会发生这个错误。

相关问题