Jdbcを使用して給与を計算するために次の方法を使用していますが、「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();
}
}
}
あなたの問題はここにあります:
_rs2 = pstmt.executeQuery(q2);
_
PreparedStatement
に、事前に準備されたSQLを実行するのではなく、SQL _q2
_を実行するように指示しています。これは次のようになります。
_rs2 = pstmt.executeQuery();
_
これはかなり一般的な間違いであり、主に_Java.sql.Statement
_とそのサブタイプの不適切なクラス設計が原因です。
@RMTが指摘しているように、ここでも同じ間違いを犯します。
_rs1 = pstmt.executeQuery(q1);
_
_q1
_にはプレースホルダーがないため、これはそれほど重要ではありません。そのため、SQLはそのまま実行されます。しかし、それはまだ間違っています。
最後に、PreparedStatement
変数を別の変数に再割り当てする前に、最初のpstmt
でclose()
を呼び出すことを検討する必要があります。そうしないと、漏れの危険があります。
そのようなpstmtのインスタンスを再利用できないことが1つの理由かもしれません。ループの各レベルで個別のPreparedStatementインスタンスを使用する必要があります。
これは1つのステートメントでも実行できることをご存知ですか?
編集:
そこにis従業員と出席の関係があるとすると、次のようなものは1回のリクエストで合計を返します。
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句を省略してください。
pstmt = conn.prepareStatement(q2);
pstmt.setInt(1,empId);
rs2 = pstmt.executeQuery(q2);
クエリq2を使用してプリペアドステートメントを作成し、変数empIdをそれにバインドしました。ここでpstmt.executeQuery(q2)を呼び出すと、変数のバインディングは失われます。 pstmt.executeQuery(q2)を実行すると、JDBCドライバーはおそらくバインドされていないSQLq2を解析します。