PL/pgSQL 函数重载

在本教程中,您将了解 PostgreSQL 中的函数重载。

摘要:在本教程中,您将了解 PostgreSQL 中的函数重载。

PL/pgSQL 函数重载简介

PostgreSQL 允许多个函数共享相同的名称,只要它们具有不同的参数即可。

如果两个或多个函数共享相同的名称,则函数名称将被重载。

当您可以调用重载函数时,PostgreSQL 会根据函数参数列表选择要执行的最佳候选函数。

以下 get_rental_duration() 函数返回指定客户的总租赁天数:

create or replace function get_rental_duration(
    p_customer_id integer
)
returns integer 
language plpgsql
as $$
declare 
    rental_duration integer; 
begin
    select 
        sum( extract(day from return_date - rental_date)) 
    into rental_duration 
    from rental 
    where customer_id = p_customer_id;

    return rental_duration;
end; $$

该 get_rental_function 函数具有 p_customer_id 作为 in 参数。

以下返回客户 ID 232 的租赁天数:

SELECT get_rental_duration(232);
get_rental_duration
---------------------
                  90
(1 row)

假设您想知道客户从特定日期到现在的租赁期限。

为此,您可以 p_from_date 在 get_retal_duration() 函数中再添加一个参数。或者您可以开发一个具有相同名称但有两个参数的新函数,如下所示:

create or replace function get_rental_duration(
    p_customer_id integer, 
    p_from_date date
)
returns integer 
language plpgsql
as $$
declare 
    rental_duration integer;
begin
    -- get the rental duration based on customer_id 
    -- and rental date
    select sum( extract( day from return_date + '12:00:00' - rental_date)) 
    into rental_duration
    from rental 
    where customer_id = p_customer_id and 
          rental_date >= p_from_date;

    -- return the rental duration in days
    return rental_duration;
end; $$

这个函数与第一个函数同名,只是它有两个参数。

换句话说, get_rental_duration(integer) 函数被函数重载 get_rental_duration(integer,date) 。

以下语句返回客户 ID 的租赁期限, 232 因为 July 1st 2005 :

SELECT get_rental_duration(232,'2005-07-01');

`get_rental_duration

              85

(1 row)`

请注意,如果省略第二个参数,PostgreSQL 将调用 get_rental_duration(integer) 具有一个参数的函数。

PL/pgSQL 函数重载和默认值

在 get_rental_duration(integer,date) 函数中,如果要为第二个参数设置默认值,如下所示:

create or replace function get_rental_duration(
    p_customer_id integer, 
    p_from_date date default '2005-01-01'
)
returns integer
language plpgsql
as $$
declare 
    rental_duration integer;
begin
    select sum( 
        extract( day from return_date + '12:00:00' - rental_date)
    ) 
    into rental_duration
    from rental 
    where customer_id= p_customer_id and 
          rental_date >= p_from_date;

    return rental_duration;

end; $$

下面调用该 get_rental_duration() 函数并传递客户 ID 232:

SELECT get_rental_duration(232);

PostgreSQL 发出错误:

ERROR:  function get_rental_duration(integer) is not unique
LINE 1: SELECT get_rental_duration(232);
               ^
HINT:  Could not choose the best candidate function. You might need to add explicit type casts.
SQL state: 42725
Character: 8

在这种情况下,PostgreSQL 无法选择最佳候选函数来执行。

在这种情况下,您具有三个功能:

get_rental_duration(p_customer_id integer);
get_rental_duration(p_customer_id integer, p_from_date date)
get_rental_duration(p_customer_id integer, p_from_date date default '2005-01-01'
)

PostgreSQL 不知道它应该执行第一个函数还是第三个函数。

根据经验,当您重载一个函数时,您应该始终使它们的参数列表唯一。

概括

  • 多个函数可以共享相同的名称,只要它们具有不同的参数即可。这些函数名被重载。
  • 使用唯一的函数参数列表来定义重载函数。