在 openGauss 5.0(或者更广泛地,在数据库系统中),函数(Function)和过程(Procedure)是两种执行特定任务的数据库对象,但它们之间存在一些关键差异。理解这些差异有助于你在数据库设计和实现中做出适当的选择。
函数(Function)
函数在数据库中用于执行特定计算或操作,并返回一个值。它可以被看作是一个封装的 SQL 语句集合,接受输入参数(可选),执行操作,并返回一个结果。在 openGauss(和大多数 SQL 数据库系统)中,函数可以用于表达式中,这意味着你可以在一个 SQL 查询中直接调用函数,并将函数返回的结果用于进一步的计算或数据检索。
示例1
CREATE OR REPLACE FUNCTION get_salary_increase(salary NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
RETURN salary * 1.1; -- 假设增加10%
END;
$$ LANGUAGE plpgsql;
-- 使用函数
SELECT get_salary_increase(1600) AS new_salary ;
superdb=> SELECT get_salary_increase(1600) AS new_salary ;
new_salary
------------
1760.0
(1 row)
示例2
CREATE FUNCTION fn_get_bal(acc_no IN NUMBER)
RETURN NUMBER
IS acc_bal NUMBER(11,2);
BEGIN
SELECT count(*)
INTO acc_bal
FROM public.t_opengauss ;
RETURN(acc_bal);
END;
/
select fn_get_bal(165);
superdb=> select fn_get_bal(165);
fn_get_bal
------------
5.00
(1 row)
过程(Procedure)
过程在数据库中执行一系列操作,但它不直接返回结果(至少不是像函数那样返回单个值)。过程可以接受输入参数和输出参数(输出参数通过其他方式访问,比如 OUT 参数或在会话状态中的更改)。过程主要用于执行需要复杂逻辑的任务,如插入、更新或删除多行数据,或者在多个步骤中更改数据库状态。
示例1
CREATE OR REPLACE PROCEDURE sp_update_employee_salary(p_id INT, p_increase NUMERIC)
AS $$
BEGIN
UPDATE employees
SET salary = salary + p_increase
WHERE id = p_id;
END;
$$ LANGUAGE plpgsql;
-- 调用过程
CALL sp_update_employee_salary(1, 1000);
示例2
CREATE OR REPLACE PROCEDURE sp_proc_case_branch(pi_result in integer, pi_return out integer)
AS
BEGIN
-- 根据pi_result的值设置pi_return
CASE pi_result
WHEN 1 THEN pi_return := 111;
WHEN 2 THEN pi_return := 222;
WHEN 3 THEN pi_return := 333;
WHEN 6 THEN pi_return := 666;
WHEN 7 THEN pi_return := 777;
WHEN 8 THEN pi_return := 888;
WHEN 9 THEN pi_return := 999;
WHEN 10 THEN pi_return := 100;
ELSE pi_return := 110;
END CASE;
-- 输出pi_return的值,用于调试或日志记录
raise info 'pi_return : %',pi_return ;
END;
/
CALL sp_proc_case_branch(3,0);
superdb=> CALL sp_proc_case_branch(3,0);
INFO: pi_return : 333
pi_return
-----------
333
(1 row)
--删除存储过程
DROP PROCEDURE proc_case_branch;
示例3
create or replace procedure sp_proc_get_msg(inout p1 text)
as
begin
raise info 'raise info procedure parameter:%',p1;
raise notice 'raise noticeprocedure parameter:%',p1;
end;
-- 调用存储过程
call sp_proc_get_msg(p1=>'sgc-dba-supermao');
superdb=> call sp_proc_get_msg(p1=>'sgc-dba-supermao');
INFO: raise info procedure parameter:sgc-dba-supermao
NOTICE: raise noticeprocedure parameter:sgc-dba-supermao
p1
------------------
sgc-dba-supermao
(1 row)
函数与过程的比较
- 返回值:函数返回一个值,而过程不直接返回任何值(虽然可以通过 OUT 参数或影响数据库状态来“返回”结果)。
- 用途:函数更适合用在需要计算结果并将其用在查询中的场景;过程则更适用于执行一系列复杂操作,这些操作可能需要多个步骤和复杂的逻辑。
- 调用方式:函数可以作为表达式的一部分被调用,而过程则通过 CALL 语句单独调用。
在选择使用函数还是过程时,应该根据具体的需求和场景来决定。如果你的任务是计算并返回一个值,那么函数是更好的选择;如果你的任务是执行一系列操作而不需要直接返回单个值,那么过程可能更合适。