Рубрики
Без рубрики

Вызываемое утверждение в примере Java

Вызываемое утверждение на Java. Пример вызываемого утверждения. Пример JDBC CallableStatement для выполнения хранимой процедуры на java. Параметр регистрации

Автор оригинала: Pankaj Kumar.

CallableStatement в java используется для вызова хранимой процедуры из программы java. Хранимые процедуры – это группа инструкций, которые мы компилируем в базе данных для какой-либо задачи. Хранимые процедуры полезны, когда мы имеем дело с несколькими таблицами со сложным сценарием, и вместо того, чтобы отправлять несколько запросов в базу данных, мы можем отправлять необходимые данные в хранимую процедуру и выполнять логику на самом сервере базы данных.

Вызываемое утверждение

API JDBC обеспечивает поддержку выполнения хранимых процедур через интерфейс CallableStatement .

Хранимые процедуры должны быть написаны в определенном синтаксисе базы данных, и для моего урока я буду использовать базу данных Oracle. Мы рассмотрим стандартные функции CallableStatement с ВХОДНЫМИ и выходными параметрами.

Позже мы рассмотрим конкретные примеры STRUCT и Курсора для Oracle.

Давайте сначала создадим таблицу для наших примеров программ CallableStatement с приведенным ниже SQL-запросом.

Давайте сначала создадим таблицу для наших примеров программ CallableStatement с приведенным ниже SQL-запросом.

-- For Oracle DB
CREATE TABLE EMPLOYEE
  (
    "EMPID"   NUMBER NOT NULL ENABLE,
    "NAME"    VARCHAR2(10 BYTE) DEFAULT NULL,
    "ROLE"    VARCHAR2(10 BYTE) DEFAULT NULL,
    "CITY"    VARCHAR2(10 BYTE) DEFAULT NULL,
    "COUNTRY" VARCHAR2(10 BYTE) DEFAULT NULL,
    PRIMARY KEY ("EMPID")
  );

Давайте сначала создадим служебный класс, чтобы получить объект подключения к базе данных Oracle. Убедитесь, что Oracle JDBC jar находится в пути сборки проекта.

Давайте сначала создадим служебный класс, чтобы получить объект подключения к базе данных Oracle. Убедитесь, что Oracle JDBC jar находится в пути сборки проекта.

package com.journaldev.jdbc.storedproc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBConnection {

	private static final String DB_DRIVER_CLASS = "oracle.jdbc.driver.OracleDriver";
	private static final String DB_URL = "jdbc:oracle:thin:@localhost:1521:orcl";
	private static final String DB_USERNAME = "HR";
	private static final String DB_PASSWORD = "oracle";
	
	public static Connection getConnection() {
		Connection con = null;
		try {
			// load the Driver Class
			Class.forName(DB_DRIVER_CLASS);

			// create the connection now
			con = DriverManager.getConnection(DB_URL,DB_USERNAME,DB_PASSWORD);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return con;
	}
}

Пример вызываемого утверждения

Давайте напишем простую хранимую процедуру для вставки данных в таблицу сотрудников.

Давайте напишем простую хранимую процедуру для вставки данных в таблицу сотрудников.

CREATE OR REPLACE PROCEDURE insertEmployee
(in_id IN EMPLOYEE.EMPID%TYPE,
 in_name IN EMPLOYEE.NAME%TYPE,
 in_role IN EMPLOYEE.ROLE%TYPE,
 in_city IN EMPLOYEE.CITY%TYPE,
 in_country IN EMPLOYEE.COUNTRY%TYPE,
 out_result OUT VARCHAR2)
AS
BEGIN
  INSERT INTO EMPLOYEE (EMPID, NAME, ROLE, CITY, COUNTRY) 
  values (in_id,in_name,in_role,in_city,in_country);
  commit;
  
  out_result := 'TRUE';
  
EXCEPTION
  WHEN OTHERS THEN 
  out_result := 'FALSE';
  ROLLBACK;
END;

Как вы можете видеть, процедура вставки сотрудника ожидает ввода данных от вызывающего абонента, которые будут вставлены в таблицу сотрудников.

Если оператор insert работает нормально, он возвращает значение TRUE, а в случае любого исключения возвращает значение FALSE.

Давайте посмотрим, как мы можем использовать CallableStatement для выполнения вставки сотрудника хранимой процедуры для вставки данных сотрудника.

Давайте посмотрим, как мы можем использовать || CallableStatement || для выполнения || вставки сотрудника || хранимой процедуры для вставки данных сотрудника.

package com.journaldev.jdbc.storedproc;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Scanner;

public class JDBCStoredProcedureWrite {

	public static void main(String[] args) {
		Connection con = null;
		CallableStatement stmt = null;
		
		//Read User Inputs
		Scanner input = new Scanner(System.in);
		System.out.println("Enter Employee ID (int):");
		int id = Integer.parseInt(input.nextLine());
		System.out.println("Enter Employee Name:");
		String name = input.nextLine();
		System.out.println("Enter Employee Role:");
		String role = input.nextLine();
		System.out.println("Enter Employee City:");
		String city = input.nextLine();
		System.out.println("Enter Employee Country:");
		String country = input.nextLine();
		
		try{
			con = DBConnection.getConnection();
			stmt = con.prepareCall("{call insertEmployee(?,?,?,?,?,?)}");
			stmt.setInt(1, id);
			stmt.setString(2, name);
			stmt.setString(3, role);
			stmt.setString(4, city);
			stmt.setString(5, country);
			
			//register the OUT parameter before calling the stored procedure
			stmt.registerOutParameter(6, java.sql.Types.VARCHAR);
			
			stmt.executeUpdate();
			
			//read the OUT parameter now
			String result = stmt.getString(6);
			
			System.out.println("Employee Record Save Success::"+result);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				stmt.close();
				con.close();
				input.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

Мы считываем данные пользователя, которые будут сохранены в таблице сотрудников. Единственное, что отличается от Подготовленного заявления , – это создание CallableStatement через ” {вызов insertEmployee(?,?,?,?,?,?)} ” и задание параметра с помощью метода CallableStatement registerOutParameter () .

Мы должны зарегистрировать параметр OUT перед выполнением хранимой процедуры. После выполнения хранимой процедуры мы можем использовать метод CallableStatement getXXX() для получения данных объекта OUT. Обратите внимание, что при регистрации параметра OUT нам необходимо указать тип параметра OUT через java.sql.Types .

Код является универсальным по своей природе, поэтому, если у нас есть такие же хранимые процедуры в других реляционных базах данных, таких как MySQL, мы также можем выполнить их с помощью этой программы.

Ниже приведены выходные данные, когда мы несколько раз выполняем приведенный выше пример программы CallableStatement.

Enter Employee ID (int):
1
Enter Employee Name:
Pankaj
Enter Employee Role:
Developer
Enter Employee City:
Bangalore
Enter Employee Country:
India
Employee Record Save Success::TRUE

-----
Enter Employee ID (int):
2
Enter Employee Name:
Pankaj Kumar
Enter Employee Role:
CEO
Enter Employee City:
San Jose
Enter Employee Country:
USA
Employee Record Save Success::FALSE

Обратите внимание, что второе выполнение завершилось неудачно, так как переданное имя превышает размер столбца. Мы используем исключение в хранимой процедуре и возвращаем значение false в этом случае.

Пример CallableStatement – Параметры вывода хранимой процедуры

Теперь давайте напишем хранимую процедуру для получения данных сотрудника по идентификатору. Пользователь введет идентификатор сотрудника, и программа отобразит информацию о сотруднике.

Теперь давайте напишем хранимую процедуру для получения данных сотрудника по идентификатору. Пользователь введет идентификатор сотрудника, и программа отобразит информацию о сотруднике.

create or replace
PROCEDURE getEmployee
(in_id IN EMPLOYEE.EMPID%TYPE,
 out_name OUT EMPLOYEE.NAME%TYPE,
 out_role OUT EMPLOYEE.ROLE%TYPE,
 out_city OUT EMPLOYEE.CITY%TYPE,
 out_country OUT EMPLOYEE.COUNTRY%TYPE
 )
AS
BEGIN
  SELECT NAME, ROLE, CITY, COUNTRY 
  INTO out_name, out_role, out_city, out_country
  FROM EMPLOYEE
  WHERE EMPID = in_id;
  
END;

Пример программы Java CallableStatement, использующей хранимую процедуру getEmployee для чтения данных о сотрудниках, является;

Пример программы Java CallableStatement, использующей хранимую процедуру getEmployee для чтения данных о сотрудниках, является;

package com.journaldev.jdbc.storedproc;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Scanner;

public class JDBCStoredProcedureRead {

	public static void main(String[] args) {
		Connection con = null;
		CallableStatement stmt = null;
		
		//Read User Inputs
		Scanner input = new Scanner(System.in);
		System.out.println("Enter Employee ID (int):");
		int id = Integer.parseInt(input.nextLine());
		
		try{
			con = DBConnection.getConnection();
			stmt = con.prepareCall("{call getEmployee(?,?,?,?,?)}");
			stmt.setInt(1, id);
			
			//register the OUT parameter before calling the stored procedure
			stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
			stmt.registerOutParameter(3, java.sql.Types.VARCHAR);
			stmt.registerOutParameter(4, java.sql.Types.VARCHAR);
			stmt.registerOutParameter(5, java.sql.Types.VARCHAR);
			
			stmt.execute();
			
			//read the OUT parameter now
			String name = stmt.getString(2);
			String role = stmt.getString(3);
			String city = stmt.getString(4);
			String country = stmt.getString(5);
			
			if(name !=null){
			System.out.println("Employee Name="+name+",Role="+role+",City="+city+",Country="+country);
			}else{
				System.out.println("Employee Not Found with ID"+id);
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				stmt.close();
				con.close();
				input.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

Опять же, программа является универсальной и работает для любой базы данных, имеющей одну и ту же хранимую процедуру. Давайте посмотрим, что будет на выходе, когда мы выполним приведенный выше пример программы CallableStatement.

Enter Employee ID (int):
1
Employee Name=Pankaj,Role=Developer,City=Bangalore,Country=India

Пример вызываемого утверждения – КУРСОР Oracle Хранимой процедуры

Поскольку мы считываем информацию о сотруднике с помощью идентификатора, мы получаем единый результат, и параметры OUT хорошо работают для считывания данных. Но если мы будем искать по роли или стране, мы можем получить несколько строк, и в этом случае мы можем использовать курсор Oracle, чтобы прочитать их как результирующий набор.

Поскольку мы считываем информацию о сотруднике с помощью идентификатора, мы получаем единый результат, и параметры OUT хорошо работают для считывания данных. Но если мы будем искать по роли или стране, мы можем получить несколько строк, и в этом случае мы можем использовать курсор Oracle, чтобы прочитать их как результирующий набор.

create or replace
PROCEDURE getEmployeeByRole
(in_role IN EMPLOYEE.ROLE%TYPE,
 out_cursor_emps OUT SYS_REFCURSOR
 )
AS
BEGIN
  OPEN out_cursor_emps FOR
  SELECT EMPID, NAME, CITY, COUNTRY 
  FROM EMPLOYEE
  WHERE ROLE = in_role;
  
END;

Поскольку мы считываем информацию о сотруднике с помощью идентификатора, мы получаем единый результат, и параметры OUT хорошо работают для считывания данных. Но если мы будем искать по роли или стране, мы можем получить несколько строк, и в этом случае мы можем использовать курсор Oracle, чтобы прочитать их как результирующий набор.

package com.journaldev.jdbc.storedproc;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

import oracle.jdbc.OracleTypes;

public class JDBCStoredProcedureCursor {

	public static void main(String[] args) {

		Connection con = null;
		CallableStatement stmt = null;
		ResultSet rs = null;
		
		//Read User Inputs
		Scanner input = new Scanner(System.in);
		System.out.println("Enter Employee Role:");
		String role = input.nextLine();
		
		try{
			con = DBConnection.getConnection();
			stmt = con.prepareCall("{call getEmployeeByRole(?,?)}");
			stmt.setString(1, role);
			
			//register the OUT parameter before calling the stored procedure
			stmt.registerOutParameter(2, OracleTypes.CURSOR);
			
			stmt.execute();
			
			//read the OUT parameter now
			rs = (ResultSet) stmt.getObject(2);
			
			while(rs.next()){
				System.out.println("Employee ID="+rs.getInt("empId")+",Name="+rs.getString("name")+
						",Role="+role+",City="+rs.getString("city")+
						",Country="+rs.getString("country"));
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				rs.close();
				stmt.close();
				con.close();
				input.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

Эта программа использует специфические классы Oracle ODBC и не будет работать с другими базами данных. Мы задаем тип параметра как OracleTypes.КУРСОР , а затем приведение его к результирующему набору объекту. Другая часть кода-простое программирование на JDBC.

Когда мы выполняем приведенный выше пример программы CallableStatement, мы получаем результат ниже.

Enter Employee Role:
Developer
Employee ID=5,Name=Kumar,Role=Developer,City=San Jose,Country=USA
Employee ID=1,Name=Pankaj,Role=Developer,City=Bangalore,Country=India

Ваши выходные данные могут отличаться в зависимости от данных в таблице сотрудников.

Пример вызываемого утверждения – Объект и СТРУКТУРА БД Oracle

Если вы посмотрите на хранимые процедуры insertEmployee и getEmployee , у меня есть все параметры таблицы сотрудников в процедуре. Когда количество столбцов увеличивается, это может привести к путанице и большей вероятности ошибок. База данных Oracle предоставляет возможность создания объекта базы данных, и мы можем использовать Oracle STRUCT для работы с ними.

Давайте сначала определим объект Oracle DB для столбцов таблицы сотрудников.

Давайте сначала определим объект Oracle DB для столбцов таблицы сотрудников.

create or replace TYPE EMPLOYEE_OBJ AS OBJECT
(
  EMPID NUMBER,
  NAME VARCHAR2(10),
  ROLE VARCHAR2(10),
  CITY  VARCHAR2(10),
  COUNTRY  VARCHAR2(10)
  
  );

Теперь давайте перепишем хранимую процедуру insertEmployee с помощью EMPLOYEE_OBJ.

Теперь давайте перепишем хранимую процедуру insertEmployee с помощью EMPLOYEE_OBJ.

CREATE OR REPLACE PROCEDURE insertEmployeeObject
(IN_EMPLOYEE_OBJ IN EMPLOYEE_OBJ,
 out_result OUT VARCHAR2)
AS
BEGIN
  INSERT INTO EMPLOYEE (EMPID, NAME, ROLE, CITY, COUNTRY) values 
  (IN_EMPLOYEE_OBJ.EMPID, IN_EMPLOYEE_OBJ.NAME, IN_EMPLOYEE_OBJ.ROLE, IN_EMPLOYEE_OBJ.CITY, IN_EMPLOYEE_OBJ.COUNTRY);
  commit;
  
  out_result := 'TRUE';
  
EXCEPTION
  WHEN OTHERS THEN 
  out_result := 'FALSE';
  ROLLBACK;
END;

Давайте посмотрим, как мы можем вызвать вставить объект сотрудника хранимую процедуру в java-программе.

Давайте посмотрим, как мы можем вызвать || вставить объект сотрудника || хранимую процедуру в java-программе.

package com.journaldev.jdbc.storedproc;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Scanner;

import oracle.jdbc.OracleCallableStatement;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;

public class JDBCStoredProcedureOracleStruct {

	public static void main(String[] args) {
		Connection con = null;
		OracleCallableStatement stmt = null;
		
		//Create Object Array for Stored Procedure call
		Object[] empObjArray = new Object[5];
		//Read User Inputs
		Scanner input = new Scanner(System.in);
		System.out.println("Enter Employee ID (int):");
		empObjArray[0] = Integer.parseInt(input.nextLine());
		System.out.println("Enter Employee Name:");
		empObjArray[1] = input.nextLine();
		System.out.println("Enter Employee Role:");
		empObjArray[2] = input.nextLine();
		System.out.println("Enter Employee City:");
		empObjArray[3] = input.nextLine();
		System.out.println("Enter Employee Country:");
		empObjArray[4] = input.nextLine();
		
		try{
			con = DBConnection.getConnection();
			
			StructDescriptor empStructDesc = StructDescriptor.createDescriptor("EMPLOYEE_OBJ", con);
			STRUCT empStruct = new STRUCT(empStructDesc, con, empObjArray);
			stmt = (OracleCallableStatement) con.prepareCall("{call insertEmployeeObject(?,?)}");
			
			stmt.setSTRUCT(1, empStruct);
			
			//register the OUT parameter before calling the stored procedure
			stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
			
			stmt.executeUpdate();
			
			//read the OUT parameter now
			String result = stmt.getString(2);
			
			System.out.println("Employee Record Save Success::"+result);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				stmt.close();
				con.close();
				input.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

Прежде всего, мы создаем массив объектов той же длины, что и объект базы данных EMPLOYEE_OBJ. Затем мы устанавливаем значения в соответствии с переменными объекта EMPLOYEE_OBJ. Это очень важно, иначе данные будут вставлены не в те столбцы.

Затем мы создаем oracle.sql.STRUCT объект с помощью oracle.sql.StructDescriptor и наш массив объектов. Как только объект СТРУКТУРЫ создан, мы устанавливаем его как параметр IN для хранимой процедуры, регистрируем параметр OUT и выполняем его. Этот код тесно связан с API JDBC и не будет работать для других баз данных.

Вот результат, когда мы выполняем эту программу.

Enter Employee ID (int):
5
Enter Employee Name:
Kumar
Enter Employee Role:
Developer
Enter Employee City:
San Jose
Enter Employee Country:
USA
Employee Record Save Success::TRUE

Мы также можем использовать объект базы данных в качестве параметра OUT и прочитать его, чтобы получить значения из базы данных.

Это все для CallableStatement в примере java для выполнения хранимых процедур, надеюсь, вы чему-то научились из него.