В этом руководстве вы узнаете, как вызвать хранимую процедуру в SQL Server из программы Java с использованием JDBC.
Это руководство начинается с того места, где закончилось руководство «Выполнение транзакции в Java».
Как вызвать хранимую процедуру из Java с помощью JDBC
Ниже приведены шаги для вызова хранимой процедуры в SQL Server из Java с использованием JDBC:
- Сначала подключитесь к базе данных SQL Server с помощью JDBC.
- Во-вторых, создайте CallableStatement для выполнения хранимой процедуры.
- В-третьих, свяжите входные параметры оператора, вызывающего хранимую процедуру.
- В-четвертых, выполните CallableStatement, который вызывает хранимую процедуру.
- В-пятых, обработайте набор результатов, возвращаемый хранимой процедурой.
- Наконец, закройте ресурсы, включая ResultSet, CallableStatement и Connection, чтобы освободить ресурсы. Если вы используете оператор try-with-resources, вам не нужно выполнять этот шаг вручную.
Создание новой хранимой процедуры
Шаг 1. Запустите Microsoft SQL Server Management Studio(SSMS) и подключитесь к SQL Server.
Шаг 2.Создайте новую хранимую процедуру, выполнив следующий оператор:
CREATE PROCEDURE GetBooksByPublishedDate
@StartDate DATE,
@EndDate DATE
AS
BEGIN
-- Check for valid date range
IF @StartDate > @EndDate
BEGIN
PRINT 'Error: Start date must be less than or equal to end date.'
RETURN
END
-- Retrieve books within the date range
SELECT BookID, Title, Publisher, ISBN, PublishedDate
FROM Books
WHERE PublishedDate BETWEEN @StartDate AND @EndDate
ORDER BY PublishedDate;
END
Хранимая процедура GetBooksByPublishedDate возвращает список книг с датами публикации между начальной и конечной датами.
Вызов хранимой процедуры
Шаг 1. Определите класс Book, который представляет каждую строку в таблице Books:
import java.time.LocalDate;
public class Book {
private int bookId;
private String title;
private String publisher;
private String isbn;
private LocalDate publishedDate;
public Book(int bookId, String title, String publisher, String isbn, LocalDate publishedDate) {
this.bookId = bookId;
this.title = title;
this.publisher = publisher;
this.isbn = isbn;
this.publishedDate = publishedDate;
}
public Book(String title, String publisher, String isbn, LocalDate publishedDate) {
this(0, title, publisher, isbn, publishedDate);
}
public int getBookId() {
return bookId;
}
public void setBookId(int bookId) {
this.bookId = bookId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public LocalDate getPublishedDate() {
return publishedDate;
}
public void setPublishedDate(LocalDate publishedDate) {
this.publishedDate = publishedDate;
}
}
Шаг 2. Определите класс BookDB для взаимодействия с базой данных BookStore:
import java.sql.Date;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.time.LocalDate;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
public class BookDB {
private final Connection connection;
public BookDB(Connection connection) {
this.connection = connection;
}
private Book createBookFrom(ResultSet rs) throws SQLException {
return new Book(
rs.getInt("BookID"),
rs.getString("Title"),
rs.getString("Publisher"),
rs.getString("ISBN"),
rs.getDate("PublishedDate").toLocalDate()
);
}
public List findByPublishedDate(LocalDate fromDate, LocalDate toDate) throws DBException {
var books = new ArrayList();
String sql = "{CALL GetBooksByPublishedDate(?, ?)}";
try(var stmt = connection.prepareCall(sql)) {
stmt.setDate(1, Date.valueOf(fromDate));
stmt.setDate(2, Date.valueOf(toDate));
try(var rs = stmt.executeQuery()) {
while(rs.next()) {
books.add(createBookFrom(rs));
}
return books;
}
} catch(SQLException e) {
throw new DBException(e.getMessage());
}
}
}
Как это работает.
Сначала определите частное поле соединения:
private final Connection connection;
Во-вторых, инициализируйте объект соединения в конструкторе:
public BookDB(Connection connection) {
this.connection = connection;
}
В-третьих, определите метод createBookFrom() для создания нового объекта Book из объекта ResultSet:
private Book createBookFrom(ResultSet rs) throws SQLException {
return new Book(
rs.getInt("BookID"),
rs.getString("Title"),
rs.getString("Publisher"),
rs.getString("ISBN"),
rs.getDate("PublishedDate").toLocalDate()
);
}
В-четвертых, определите метод findByPublishedDate, который возвращает список объектов Book с датой публикации между fromDate и toDate:
public List findByPublishedDate(LocalDate fromDate, LocalDate toDate) throws DBException {
В-пятых, инициализируем объект списка книг:
var books = new ArrayList();
В-шестых, создайте оператор T-SQL, который вызывает хранимую процедуру:
String sql = "{CALL GetBooksByPublishedDate(?, ?)}";
Вопросительные знаки(?) являются заполнителями для параметров хранимой процедуры GetBooksByPublishedDate. При выполнении хранимой процедуры необходимо задать фактические значения этих параметров.
В-седьмых, создайте объект CallableStatemen:
try(var stmt = connection.prepareCall(sql)) {
В-восьмых, привяжите даты к параметрам запроса:
stmt.setDate(1, Date.valueOf(fromDate)); stmt.setDate(2, Date.valueOf(toDate));
Девятое, выполните вызов хранимой процедуры:
try(var rs = stmt.executeQuery()) {
В-десятых, выполните итерацию по строкам в результирующем наборе, преобразуйте каждую строку в объект Book и добавьте его в список книг:
while(rs.next()) {
books.add(createBookFrom(rs));
}
Одиннадцатое, верните список книг:
return books;
Наконец, выдайте исключение DBException, если во время вызова возникнет какая-либо ошибка:
} catch(SQLException e) {
throw new DBException(e.getMessage());
}
Шаг 3. Измените метод main() класса Main, чтобы использовать метод findByPublishedDate класса BookDB:
import java.sql.SQLException;
import java.time.LocalDate;
public class Main {
public static void main(String[] args) {
try(var connection = SQLServerConnection.connect()) {
//
var bookDB = new BookDB(connection);
var fromDate = LocalDate.of(2021,1,1);
var toDate = LocalDate.of(2022,12,31);
var books = bookDB.findByPublishedDate(fromDate, toDate );
for(var book: books) {
System.out.println(book.getTitle() + '\t' + book.getPublishedDate());
}
} catch(SQLException | DBException e) {
System.err.println(e.getMessage());
}
}
}
Как это работает.
Сначала подключитесь к SQL Server:
try(var connection = SQLServerConnection.connect()) {
Во-вторых, создайте объект BookDB:
var bookDB = new BookDB(connection);
В-третьих, инициализируйте переменные, хранящие даты для передачи в метод findByPublishedDate:
var fromDate = LocalDate.of(2021, 1, 1); var toDate = LocalDate.of(2022, 12, 31);
В-четвертых, выполните метод findByPublishedDate объекта bookDB для вызова хранимой процедуры:
var books = bookDB.findByPublishedDate(fromDate, toDate );
В-пятых, пройдитесь по списку книг и отобразите название книги и дату публикации:
for(var book: books) {
System.out.println(book.getTitle() + '\t' + book.getPublishedDate());
}
Наконец, отобразите сообщение об ошибке:
} catch(SQLException | DBException e) {
System.err.println(e.getMessage());
}
Шаг 4. Запустите программу.
Будет выведен следующий результат:
Inside SQL Server 2021-07-20 SQL Server Performance Tuning 2022-04-15 SQL Server Internals: A Deep Dive 2022-12-15
Загрузите исходный код проекта
Загрузите исходный код проекта
Краткое содержание
- Используйте объект CallableStatement для вызова хранимой процедуры.
