"Ошибка ORA-01008: не все переменные"
Я использую следующий метод расчета заработной платы с помощью 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();
}
}
}
Ответы
Ответ 1
Ваша проблема здесь:
rs2 = pstmt.executeQuery(q2);
Вы сообщаете PreparedStatement
выполнить SQL q2
, вместо того, чтобы выполнять SQL, предварительно подготовленный. Это должно быть просто:
rs2 = pstmt.executeQuery();
Это довольно распространенная ошибка, вызванная главным образом плохим дизайном класса java.sql.Statement
и его подтипами.
Как указывает @RMT, вы делаете ту же ошибку:
rs1 = pstmt.executeQuery(q1);
Это не имеет большого значения, поскольку в q1
нет заполнителей, поэтому SQL выполняется как есть. Это все еще неправильно.
Наконец, вы должны рассмотреть возможность вызова close()
на первом PreparedStatement
, прежде чем pstmt
переменную pstmt
на другую. Вы рискуете утечкой, если вы этого не сделаете.
Ответ 2
Одна из причин может заключаться в том, что вы не можете повторно использовать экземпляр 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
Если на самом деле посещаемость не связана с сотрудником, просто оставьте предложение where во вложенном элементе.
Ответ 3
pstmt = conn.prepareStatement(q2);
pstmt.setInt(1,empId);
rs2 = pstmt.executeQuery(q2);
Вы уже создали подготовленный оператор с запросом q2 и связали с ним переменную empId. если вы теперь вызываете pstmt.executeQuery(q2), привязка переменной теряется. Драйвер JDBC, вероятно, анализирует unbound sql q2 при выполнении pstmt.executeQuery(q2).
Ответ 4
UPDATE TESTCP SET CP_KEY2 =?, CP_DESC =?, CP_MAKER =?, CP_MAKER_DT = SYSDATE, CP_STATUS = 'M' WHERE CP_LANGUAGE =? И CP_ENG_CODE =? И CP_KEY1 =? И CP_LANGUAGE =?
В приведенном выше запросе мы имеем 7 в параметре, но если в вашем java-коде PreparedStatement вы установили только 6 значений параметров.
Тогда и эта ошибка произойдет.