---
title: "创建函数 - OceanBase 数据库 V4.2.1 | OceanBase 文档中心"
description: "创建函数 PL 函数是由一个或多个 SQL 语句组成的子程序，可重复执行。函数只能返回一个变量，并且必须包含一个有效的 RETURN 语句。 功能适用性 该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版仅提供 MySQL 模式。 创建函数的基本语法如下： CREATE [OR REP…"
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.2.1 LTS

# 创建函数

更新时间：2026-07-15 22:01:31

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.2.1/zh-CN/700.reference/500.sql-reference/300.pl-reference/300.pl-oracle/700.stored-procedure-and-functions-oracle/300.create-a-function-oracle.md)  

PL 函数是由一个或多个 SQL 语句组成的子程序，可重复执行。函数只能返回一个变量，并且必须包含一个有效的 `RETURN` 语句。

#### 功能适用性

该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版仅提供 MySQL 模式。

创建函数的基本语法如下：

```javascript
CREATE [OR REPLACE] FUNCTION function_name
[ (argment [ { IN | IN OUT }] Type,
      argment [ { IN | OUT | IN OUT } ] Type ]
    [ AUTHID DEFINER | CURRENT_USER ]
RETURN return_type
{ IS | AS }
 delarification_block
BEGIN
    FUNCTION_body
EXCEPTION
    exception_handler
END;

```

示例如下：

```javascript
obclient> CREATE TABLE employees(  
       empno          NUMBER(4,0),  
       empname        VARCHAR(10),  
       job            VARCHAR(10),
      deptno          NUMBER(2,0),
      salary          NUMERIC  
   );
Query OK, 0 rows affected

obclient> INSERT INTO employees VALUES (200,'Jennifer','AD_ASST',1,15000),
       (202,'Pat','MK_REP',3,12000),(119,'Karen','PU_CLERK', 4,10000),(201,'Michael','MK_MAN',3,9000);
Query OK, 4 rows affected )
Records: 4  Duplicates: 0  Warnings: 0

obclient> CREATE OR REPLACE FUNCTION get_salary_by_dept(
       v_in_dept_id NUMBER,
       v_out_emp_count OUT NUMBER)
       RETURN NUMBER
   IS
       v_sum NUMBER;
   BEGIN
       SELECT SUM(salary), count(*) INTO v_sum, v_out_emp_count
           FROM employees WHERE deptno=v_in_dept_id;
       RETURN v_sum;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         DBMS_OUTPUT.PUT_LINE('Dept id '||v_in_dept_id||' not found');
      WHEN OTHERS THEN
         DBMS_OUTPUT.PUT_LINE('ERR: '||SQLCODE||': '||SQLERRM);
   END get_salary_by_dept;
/
Query OK, 0 rows affected

```

## 参数的传递

向函数中传递参数有如下三种方法：

- 位置表示法。

  按照参数定义的顺序逐个传入，语法是 `argument_value1[,argument_value2 ...]`

  示例如下：

  ```sql
  obclient> DECLARE
           v_num NUMBER;
           v_sum NUMBER;
       BEGIN
           v_sum :=get_salary_by_dept(3, v_num);
           DBMS_OUTPUT.PUT_LINE('Total salary: '||v_sum);
           DBMS_OUTPUT.PUT_LINE('Total amount of person: '||v_num);
       END;
       /
  Query OK, 0 rows affected

  Total salary: 21000
  Total amount of person: 2

  ```
 - 名称表示法。

  显式地指定参数名和传入值，不必按照参数定义的顺序，语法是 `argument1 => parameter1 [, argument2 => parameter2[, ...]]`

  示例如下：

  ```sql
  obclient> DECLARE
           v_num NUMBER;
           v_sum NUMBER;
       BEGIN
           v_sum :=get_salary_by_dept(v_out_emp_count => v_num, v_in_dept_id => 3 );
           DBMS_OUTPUT.PUT_LINE('Total salary: '||v_sum);
           DBMS_OUTPUT.PUT_LINE('Total amount of person: '||v_num);
           END;
       /
  Query OK, 0 rows affected

  ```
 - 混合表示法。

  同时使用位置表示法和名称表示法为函数传递参数。采用这种参数传递方法时，使用位置表示法所传递的参数必须放在名称表示法所传递的参数前面。也就是说，无论函数具有多少个参数，只要其中有一个参数使用名称表示法，其后所有的参数都必须使用名称表示法。

  示例如下：

  ```sql
  obclient> DECLARE
           v_num NUMBER;
           v_sum NUMBER;
       BEGIN
           v_sum :=get_salary_by_dept(3, v_out_emp_count => v_num );
           DBMS_OUTPUT.PUT_LINE('Total salary: '||v_sum);
           DBMS_OUTPUT.PUT_LINE('Total amount of person: '||v_num);
       END;
       /
  Query OK, 0 rows affected

  ```

## 参数默认值

在 `CREATE OR REPLACE FUNCTION` 语句中声明函数参数时可以使用 `DEFAULT` 关键字作为输入参数指定默认值。示例如下：

```javascript
CREATE OR REPLACE FUNCTION demo_def_args(
    name VARCHAR2,
    age INTEGER,
    -- 如果 gender 不传入值，则默认为 male
    gender VARCHAR2 DEFAULT 'Male')
    RETURN VARCHAR2
AS
    V_var VARCHAR2(32);
BEGIN
    V_var := name||', '||gender||', '||TO_CHAR(age)||' years old.';
    RETURN v_var;
END;

```

具有默认值的函数创建后，在函数调用时，如果没有为具有默认值的参数提供实际参数值，函数将使用该参数的默认值。但当调用者为默认参数提供实际参数时，函数将使用实际参数值。在创建函数时，只能为输入参数设置默认值，而不能为输入/输出参数设置默认值。

```javascript
obclient> DECLARE
     Var VARCHAR(32);
     BEGIN
         Var := demo_def_args('Roger', 30);
         DBMS_OUTPUT.PUT_LINE(var);

         Var := demo_def_args('Allen', age => 40);
         DBMS_OUTPUT.PUT_LINE(var);

         Var := demo_def_args('Tracy', gender => 'Female', age => 20);
         DBMS_OUTPUT.PUT_LINE(var);
     END;
     /
Query OK, 0 rows affected

Roger, Male, 30 years old.
Allen, Male, 40 years old.
Tracy, Female, 20 years old.

```

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
