在PL/SQL中,FUNCTION
、PROCEDURE
和 PACKAGE
是三种不同的程序单元,它们各自有特定的用途和特性。下面将通过思维导图的形式来概述它们的区别,并提供相应的代码示例。
思维导图结构
- PL/SQL 程序单元
- FUNCTION
- 定义
- 返回一个值
- 使用场景
- 计算并返回结果
- SQL语句中使用
- 特点
- 必须有RETURN语句
- 可以有输入参数
- PROCEDURE
- 定义
- 执行一系列操作
- 使用场景
- 数据库操作(增删改查)
- 不需要返回值
- 特点
- 可以有输入输出参数
- 不需要RETURN语句
- PACKAGE
- 定义
- 组织多个相关对象
- 使用场景
- 封装和组织函数、过程和其他对象
- 提供私有和公共接口
- 特点
- 包含声明部分和可选的主体部分
- 支持封装、重载、全局变量
代码示例
FUNCTION 示例
CREATE OR REPLACE FUNCTION get_employee_salary (emp_id IN NUMBER)
RETURN NUMBER IS
emp_salary NUMBER;
BEGIN
SELECT salary INTO emp_salary FROM employees WHERE employee_id = emp_id;
RETURN emp_salary;
END;
/
此函数接收员工ID作为参数,并返回该员工的薪水。它可以在SQL查询中被调用,例如:
SELECT get_employee_salary(101) FROM dual;
PROCEDURE 示例
CREATE OR REPLACE PROCEDURE update_employee_salary (
emp_id IN NUMBER,
new_salary IN NUMBER
) IS
BEGIN
UPDATE employees SET salary = new_salary WHERE employee_id = emp_id;
COMMIT;
END;
/
这个过程接收员工ID和新的薪水作为参数,并更新数据库中的相应记录。
PACKAGE 示例
CREATE OR REPLACE PACKAGE emp_mgmt IS
-- Public declarations
FUNCTION hire_employee (emp_name VARCHAR2, job_id VARCHAR2, salary NUMBER) RETURN NUMBER;
PROCEDURE fire_employee (emp_id NUMBER);
-- Private declarations can be placed here in the package body
END emp_mgmt;
/
CREATE OR REPLACE PACKAGE BODY emp_mgmt IS
FUNCTION hire_employee (emp_name VARCHAR2, job_id VARCHAR2, salary NUMBER) RETURN NUMBER IS
emp_id NUMBER;
BEGIN
INSERT INTO employees (employee_name, job_id, salary) VALUES (emp_name, job_id, salary) RETURNING employee_id INTO emp_id;
RETURN emp_id;
END;
PROCEDURE fire_employee (emp_id NUMBER) IS
BEGIN
DELETE FROM employees WHERE employee_id = emp_id;
COMMIT;
END;
END emp_mgmt;
/
在这个包中,hire_employee
函数用于雇佣新员工并返回新生成的员工ID,而 fire_employee
过程用于解雇员工。这些成员可以通过 emp_mgmt
包名进行访问。
Java 应用层考虑
在Java应用程序中,您可以使用JDBC API来调用上述定义的PL/SQL程序单元。例如,调用存储过程或函数可以如下所示:
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Types;
public class PlsqlCaller {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@localhost:1521:ORCL";
String user = "your_username";
String password = "your_password";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
// 调用 FUNCTION
try (CallableStatement csFunc = conn.prepareCall("{? = call get_employee_salary(?)}")) {
csFunc.registerOutParameter(1, Types.NUMERIC);
csFunc.setInt(2, 101); // 假设员工ID为101
csFunc.execute();
System.out.println("Employee Salary: " + csFunc.getInt(1));
}
// 调用 PROCEDURE
try (CallableStatement csProc = conn.prepareCall("{call update_employee_salary(?, ?)}")) {
csProc.setInt(1, 101); // 假设员工ID为101
csProc.setDouble(2, 80000.00); // 新的薪水
csProc.execute();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
对于包中的成员,您同样可以使用类似的JDBC调用来执行它们。请注意,实际应用中应加入适当的错误处理和资源管理。
标签:salary,FUNCATION,PACKAGE,示例,NUMBER,emp,employee,id,PROCEDURE From: https://blog.csdn.net/qq_33240556/article/details/144956635