CallableStatement เป็น Interface สำหรับเรียกใช้ Stored Procedure ในฐานข้อมูลผ่าน JDBC ให้ใช้งานได้อย่างมาตรฐาน (Database Agnostic)
การสร้าง CallableStatement
// Syntax: {call procedure_name(?, ?, ?)}
CallableStatement cstmt = con.prepareCall("{call myProcedure(?, ?, ?)}");
ตั้งค่าพารามิเตอร์ Input (IN)
cstmt.setString(1, "Raghav"); // พารามิเตอร์ที่ 1 cstmt.setInt(2, 3000); // พารามิเตอร์ที่ 2 cstmt.setString(3, "Hyderabad"); // พารามิเตอร์ที่ 3
จัดการพารามิเตอร์ Output (OUT) และ INOUT
// ลงทะเบียน OUT parameter ก่อน Execute cstmt.registerOutParameter(4, Types.INTEGER); // พารามิเตอร์ที่ 4 เป็น OUT cstmt.registerOutParameter(5, Types.VARCHAR); // พารามิเตอร์ที่ 5 เป็น OUT // Execute cstmt.execute(); // อ่านค่า OUT int resultCode = cstmt.getInt(4); String resultMsg = cstmt.getString(5);
ตัวอย่างครบถ้วน: Stored Procedure ที่มี IN และ OUT
MySQL Stored Procedure:
CREATE PROCEDURE get_employee_info(
IN emp_id INT,
OUT emp_name VARCHAR(100),
OUT emp_salary DECIMAL(10,2),
OUT emp_dept VARCHAR(50)
)
BEGIN
SELECT name, salary, department
INTO emp_name, emp_salary, emp_dept
FROM employees WHERE id = emp_id;
END;
Java Code:
import java.sql.*;
public class CallableStatementExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false";
String user = "root";
String password = "password";
try (Connection con = DriverManager.getConnection(url, user, password);
CallableStatement cstmt = con.prepareCall("{call get_employee_info(?, ?, ?, ?)}")) {
// Set IN parameter
cstmt.setInt(1, 101);
// Register OUT parameters
cstmt.registerOutParameter(2, Types.VARCHAR);
cstmt.registerOutParameter(3, Types.DECIMAL);
cstmt.registerOutParameter(4, Types.VARCHAR);
// Execute
cstmt.execute();
// Get OUT parameters
String name = cstmt.getString(2);
BigDecimal salary = cstmt.getBigDecimal(3);
String dept = cstmt.getString(4);
System.out.println("Name: " + name);
System.out.println("Salary: " + salary);
System.out.println("Department: " + dept);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
ข้อดีของ CallableStatement
- รองรับ Stored Procedure ทุก Database ด้วย Syntax เดียวกัน (
{call ...}) - จัดการ IN, OUT, INOUT Parameters ได้
- ลด Network Traffic (ประมวลผลบน Server)
- เพิ่มความปลอดภัย (Encapsulation Business Logic)
MySQL 8.0+ รองรับ Result Sets จาก Procedure
// Procedure ที่ RETURN RESULT SET
CREATE PROCEDURE get_all_employees()
BEGIN
SELECT * FROM employees;
END;
// Java
try (CallableStatement cstmt = con.prepareCall("{call get_all_employees()}")) {
boolean hasResults = cstmt.execute();
if (hasResults) {
try (ResultSet rs = cstmt.getResultSet()) {
while (rs.next()) { /* process */ }
}
}
}