JDBC - Thủ tục được lưu trữ

Chúng tôi đã học cách sử dụng Stored Procedurestrong JDBC trong khi thảo luận về chương JDBC - Tuyên bố . Chương này tương tự như phần đó, nhưng nó sẽ cung cấp cho bạn thông tin bổ sung về cú pháp thoát SQL của JDBC.

Cũng giống như một đối tượng Connection tạo ra các đối tượng Statement và PreparedStatement, nó cũng tạo ra đối tượng CallableStatement, đối tượng này sẽ được sử dụng để thực hiện một lệnh gọi đến một thủ tục được lưu trữ trong cơ sở dữ liệu.

Tạo đối tượng CallableStatement

Giả sử, bạn cần thực hiện thủ tục lưu trữ Oracle sau:

CREATE OR REPLACE PROCEDURE getEmpName 
   (EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) AS
BEGIN
   SELECT first INTO EMP_FIRST
   FROM Employees
   WHERE ID = EMP_ID;
END;

NOTE: Thủ tục được lưu trữ ở trên đã được viết cho Oracle, nhưng chúng tôi đang làm việc với cơ sở dữ liệu MySQL, vì vậy, chúng ta hãy viết cùng một quy trình được lưu trữ cho MySQL như sau để tạo nó trong cơ sở dữ liệu EMP -

DELIMITER $$

DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
CREATE PROCEDURE `EMP`.`getEmpName` 
   (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
BEGIN
   SELECT first INTO EMP_FIRST
   FROM Employees
   WHERE ID = EMP_ID;
END $$

DELIMITER ;

Ba loại tham số tồn tại: IN, OUT và INOUT. Đối tượng PreparedStatement chỉ sử dụng tham số IN. Đối tượng CallableStatement có thể sử dụng cả ba.

Dưới đây là định nghĩa của mỗi -

Tham số Sự miêu tả
TRONG Một tham số có giá trị không xác định khi câu lệnh SQL được tạo. Bạn liên kết các giá trị với tham số IN bằng các phương thức setXXX ().
NGOÀI Một tham số có giá trị được cung cấp bởi câu lệnh SQL mà nó trả về. Bạn lấy các giá trị từ các tham số OUT bằng các phương thức getXXX ().
GIỚI THIỆU Một tham số cung cấp cả giá trị đầu vào và đầu ra. Bạn liên kết các biến với phương thức setXXX () và truy xuất giá trị bằng phương thức getXXX ().

Đoạn mã sau đây cho thấy cách sử dụng Connection.prepareCall() phương pháp để khởi tạo một CallableStatement đối tượng dựa trên thủ tục được lưu trữ trước đó -

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

Biến chuỗi SQL đại diện cho thủ tục được lưu trữ, với trình giữ chỗ tham số.

Sử dụng các đối tượng CallableStatement giống như sử dụng các đối tượng PreparedStatement. Bạn phải liên kết các giá trị với tất cả các tham số trước khi thực hiện câu lệnh, nếu không bạn sẽ nhận được một SQLException.

Nếu bạn có tham số IN, chỉ cần tuân theo các quy tắc và kỹ thuật tương tự áp dụng cho đối tượng PreparedStatement; sử dụng phương thức setXXX () tương ứng với kiểu dữ liệu Java mà bạn đang ràng buộc.

Khi bạn sử dụng các tham số OUT và INOUT, bạn phải sử dụng một phương thức CallableStatement bổ sung, registerOutParameter (). Phương thức registerOutParameter () liên kết kiểu dữ liệu JDBC với kiểu dữ liệu mà thủ tục được lưu trữ sẽ trả về.

Khi bạn gọi thủ tục đã lưu trữ của mình, bạn lấy giá trị từ tham số OUT bằng phương thức getXXX () thích hợp. Phương thức này chuyển giá trị truy xuất của kiểu SQL sang kiểu dữ liệu Java.

Đóng đối tượng CallableStatement

Cũng giống như bạn đóng đối tượng Statement khác, vì lý do tương tự, bạn cũng nên đóng đối tượng CallableStatement.

Một cuộc gọi đơn giản đến phương thức close () sẽ thực hiện công việc. Nếu bạn đóng đối tượng Connection trước, nó cũng sẽ đóng đối tượng CallableStatement. Tuy nhiên, bạn phải luôn đóng đối tượng CallableStatement một cách rõ ràng để đảm bảo dọn dẹp đúng cách.

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   cstmt.close();
}

Chúng tôi đã nghiên cứu thêm chi tiết trong Mã ví dụ - Có thể gọi .

Cú pháp thoát SQL JDBC

Cú pháp thoát cung cấp cho bạn sự linh hoạt để sử dụng các tính năng cụ thể của cơ sở dữ liệu không có sẵn cho bạn bằng cách sử dụng các phương thức và thuộc tính JDBC chuẩn.

Định dạng cú pháp thoát SQL chung như sau:

{keyword 'parameters'}

Dưới đây là các trình tự thoát sau, bạn sẽ thấy rất hữu ích khi thực hiện lập trình JDBC -

d, t, ts Từ khóa

Chúng giúp xác định ngày, giờ và các ký tự dấu thời gian. Như bạn đã biết, không có hai DBMS nào biểu thị thời gian và ngày tháng giống nhau. Cú pháp thoát này yêu cầu trình điều khiển hiển thị ngày hoặc giờ theo định dạng của cơ sở dữ liệu đích. Ví dụ -

{d 'yyyy-mm-dd'}

Trong đó yyyy = năm, mm = tháng; dd = ngày. Sử dụng cú pháp này {d '2009-09-03'} là ngày 9 tháng 3 năm 2009.

Dưới đây là một ví dụ đơn giản cho thấy cách CHÈN ngày trong bảng -

//Create a Statement object
stmt = conn.createStatement();
//Insert data ==> ID, First Name, Last Name, DOB
String sql="INSERT INTO STUDENTS VALUES" +
             "(100,'Zara','Ali', {d '2001-12-16'})";

stmt.executeUpdate(sql);

Tương tự, bạn có thể sử dụng một trong hai cú pháp sau, t hoặc là ts -

{t 'hh:mm:ss'}

Trong đó hh = giờ; mm = phút; ss = giây. Sử dụng cú pháp này {t '13: 30: 29'} là 1:30:29 CH.

{ts 'yyyy-mm-dd hh:mm:ss'}

Đây là cú pháp kết hợp của hai cú pháp trên cho 'd' và 't' để biểu thị dấu thời gian.

từ khóa thoát

Từ khóa này xác định ký tự thoát được sử dụng trong mệnh đề LIKE. Hữu ích khi sử dụng ký tự đại diện SQL%, ký tự này khớp với không hoặc nhiều ký tự. Ví dụ -

String sql = "SELECT symbol FROM MathSymbols
              WHERE symbol LIKE '\%' {escape '\'}";
stmt.execute(sql);

Nếu bạn sử dụng ký tự gạch chéo ngược (\) làm ký tự thoát, bạn cũng phải sử dụng hai ký tự gạch chéo ngược trong chuỗi ký tự Java của mình, vì dấu gạch chéo ngược cũng là ký tự thoát Java.

fn Từ khóa

Từ khóa này đại diện cho các hàm vô hướng được sử dụng trong DBMS. Ví dụ: bạn có thể sử dụng độ dài hàm SQL để lấy độ dài của một chuỗi -

{fn length('Hello World')}

Điều này trả về 11, độ dài của chuỗi ký tự 'Hello World'.

gọi từ khóa

Từ khóa này được sử dụng để gọi các thủ tục được lưu trữ. Ví dụ: đối với một thủ tục được lưu trữ yêu cầu tham số IN, hãy sử dụng cú pháp sau:

{call my_procedure(?)};

Đối với thủ tục được lưu trữ yêu cầu tham số IN và trả về tham số OUT, hãy sử dụng cú pháp sau:

{? = call my_procedure(?)};

oj Từ khóa

Từ khóa này được sử dụng để biểu thị các liên kết bên ngoài. Cú pháp như sau:

{oj outer-join}

Trường hợp ngoài tham gia = bảng {LEFT | RIGHT | FULL} OUTERJOIN {bảng | ngoài-tham gia} với điều kiện tìm kiếm. Ví dụ -

String sql = "SELECT Employees 
              FROM {oj ThisTable RIGHT
              OUTER JOIN ThatTable on id = '100'}";
stmt.execute(sql);